From: Eli Zaretskii Date: Sat, 27 Jan 2007 12:30:46 +0000 (+0000) Subject: * cli/cli-script.c: Include breakpoint.h. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=40c03ae8b35379347d3afea7bd4ddcb6cc7425c7;p=binutils-gdb.git * cli/cli-script.c: Include breakpoint.h. (build_command_line): Require arguments only for if and while commands. (get_command_line, execute_user_command, execute_control_command): Fix wording of warning messages. (print_command_lines): Print breakpoint commands. (execute_control_command): Call commands_from_control_command to handle the `commands' command inside a body of a flow-control command. (read_next_line): Recognize the `commands' command and build a command line structure for it. (recurse_read_control_structure, read_command_lines): Handle `commands' similarly to `if' and `while'. * breakpoint.c (get_number_trailer): Document the special meaning of NULL as the first argument PP. (commands_from_control_command): New function. * breakpoint.h (commands_from_control_command): Add prototype. * defs.h (commands_control): New enumerated value for enum command_control_type. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a21ec4a25ee..a6ef394d30e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,28 @@ +2007-01-27 Eli Zaretskii + + * cli/cli-script.c: Include breakpoint.h. + (build_command_line): Require arguments only for if and while + commands. + (get_command_line, execute_user_command, execute_control_command): + Fix wording of warning messages. + (print_command_lines): Print breakpoint commands. + (execute_control_command): Call commands_from_control_command to + handle the `commands' command inside a body of a flow-control + command. + (read_next_line): Recognize the `commands' command and build a + command line structure for it. + (recurse_read_control_structure, read_command_lines): Handle + `commands' similarly to `if' and `while'. + + * breakpoint.c (get_number_trailer): Document the special meaning + of NULL as the first argument PP. + (commands_from_control_command): New function. + + * breakpoint.h (commands_from_control_command): Add prototype. + + * defs.h (commands_control): New enumerated value for enum + command_control_type. + 2007-01-26 Joel Brobecker * ada-lang.c (ada_exception_breakpoint_ops): Fix typo in function name. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 2a5e81f7764..e50c99a1f9b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -403,6 +403,8 @@ int default_breakpoint_line; Currently the string can either be a number or "$" followed by the name of a convenience variable. Making it an expression wouldn't work well for map_breakpoint_numbers (e.g. "4 + 5 + 6"). + + If the string is a NULL pointer, that denotes the last breakpoint. TRAILER is a character which can be found after the number; most commonly this is `-'. If you don't want a trailer, use \0. */ @@ -647,6 +649,52 @@ commands_command (char *arg, int from_tty) } error (_("No breakpoint number %d."), bnum); } + +/* Like commands_command, but instead of reading the commands from + input stream, takes them from an already parsed command structure. + + This is used by cli-script.c to DTRT with breakpoint commands + that are part of if and while bodies. */ +enum command_control_type +commands_from_control_command (char *arg, struct command_line *cmd) +{ + struct breakpoint *b; + char *p; + int bnum; + + /* If we allowed this, we would have problems with when to + free the storage, if we change the commands currently + being read from. */ + + if (executing_breakpoint_commands) + error (_("Can't use the \"commands\" command among a breakpoint's commands.")); + + /* An empty string for the breakpoint number means the last + breakpoint, but get_number expects a NULL pointer. */ + if (arg && !*arg) + p = NULL; + else + p = arg; + bnum = get_number (&p); + + if (p && *p) + error (_("Unexpected extra arguments following breakpoint number.")); + + ALL_BREAKPOINTS (b) + if (b->number == bnum) + { + free_command_lines (&b->commands); + if (cmd->body_count != 1) + error (_("Invalid \"commands\" block structure.")); + /* We need to copy the commands because if/while will free the + list after it finishes execution. */ + b->commands = copy_command_lines (cmd->body_list[0]); + breakpoints_changed (); + breakpoint_modify_event (b->number); + return simple_control; + } + error (_("No breakpoint number %d."), bnum); +} /* Like target_read_memory() but if breakpoints are inserted, return the shadow contents instead of the breakpoints themselves. diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 79f1c1fcaf0..9eebfc8761d 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -759,6 +759,10 @@ extern void disable_watchpoints_before_interactive_call_start (void); extern void enable_watchpoints_after_interactive_call_stop (void); +/* For script interpreters that need to define breakpoint commands + after they've already read the commands into a struct command_line. */ +extern enum command_control_type commands_from_control_command + (char *arg, struct command_line *cmd); extern void clear_breakpoint_hit_counts (void); diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c index a27e971c017..ad64a4a65b1 100644 --- a/gdb/cli/cli-script.c +++ b/gdb/cli/cli-script.c @@ -30,6 +30,7 @@ #include "gdb_string.h" #include "exceptions.h" #include "top.h" +#include "breakpoint.h" #include "cli/cli-cmds.h" #include "cli/cli-decode.h" #include "cli/cli-script.h" @@ -82,7 +83,7 @@ build_command_line (enum command_control_type type, char *args) { struct command_line *cmd; - if (args == NULL) + if (args == NULL && (type == if_control || type == while_control)) error (_("if/while commands require arguments.")); cmd = (struct command_line *) xmalloc (sizeof (struct command_line)); @@ -115,7 +116,7 @@ get_command_line (enum command_control_type type, char *arg) /* Read in the body of this command. */ if (recurse_read_control_structure (cmd) == invalid_control) { - warning (_("Error reading in control structure.")); + warning (_("Error reading in canned sequence of commands.")); do_cleanups (old_chain); return NULL; } @@ -207,6 +208,23 @@ print_command_lines (struct ui_out *uiout, struct command_line *cmd, continue; } + /* A commands command. Print the breakpoint commands and continue. */ + if (list->control_type == commands_control) + { + if (*(list->line)) + ui_out_field_fmt (uiout, NULL, "commands %s", list->line); + else + ui_out_field_string (uiout, NULL, "commands"); + ui_out_text (uiout, "\n"); + print_command_lines (uiout, *list->body_list, depth + 1); + if (depth) + ui_out_spaces (uiout, 2 * depth); + ui_out_field_string (uiout, NULL, "end"); + ui_out_text (uiout, "\n"); + list = list->next; + continue; + } + /* ignore illegal command type and try next */ list = list->next; } /* while (list) */ @@ -292,7 +310,7 @@ execute_user_command (struct cmd_list_element *c, char *args) ret = execute_control_command (cmdlines); if (ret != simple_control && ret != break_control) { - warning (_("Error in control structure.")); + warning (_("Error executing canned sequence of commands.")); break; } cmdlines = cmdlines->next; @@ -498,9 +516,20 @@ execute_control_command (struct command_line *cmd) break; } + case commands_control: + { + /* Breakpoint commands list, record the commands in the breakpoint's + command list and return. */ + new_line = insert_args (cmd->line); + if (!new_line) + break; + make_cleanup (free_current_contents, &new_line); + ret = commands_from_control_command (new_line, cmd); + break; + } default: - warning (_("Invalid control type in command structure.")); + warning (_("Invalid control type in canned commands structure.")); break; } @@ -849,6 +878,14 @@ read_next_line (struct command_line **command) 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 == 10 && !strncmp (p, "loop_break", 10)) { *command = (struct command_line *) @@ -924,9 +961,10 @@ recurse_read_control_structure (struct command_line *current_cmd) if (val == end_command) { if (current_cmd->control_type == while_control - || current_cmd->control_type == if_control) + || current_cmd->control_type == if_control + || current_cmd->control_type == commands_control) { - /* Success reading an entire control structure. */ + /* Success reading an entire canned sequence of commands. */ ret = simple_control; break; } @@ -974,7 +1012,8 @@ recurse_read_control_structure (struct command_line *current_cmd) /* If the latest line is another control structure, then recurse on it. */ if (next->control_type == while_control - || next->control_type == if_control) + || next->control_type == if_control + || next->control_type == commands_control) { control_level++; ret = recurse_read_control_structure (next); @@ -1045,7 +1084,8 @@ read_command_lines (char *prompt_arg, int from_tty) } if (next->control_type == while_control - || next->control_type == if_control) + || next->control_type == if_control + || next->control_type == commands_control) { control_level++; ret = recurse_read_control_structure (next); diff --git a/gdb/defs.h b/gdb/defs.h index c7e6d3a51be..beb1a3b2ac6 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -691,6 +691,7 @@ enum command_control_type continue_control, while_control, if_control, + commands_control, invalid_control };