* cli/cli-script.c: Include breakpoint.h.
authorEli Zaretskii <eliz@gnu.org>
Sat, 27 Jan 2007 12:30:46 +0000 (12:30 +0000)
committerEli Zaretskii <eliz@gnu.org>
Sat, 27 Jan 2007 12:30:46 +0000 (12:30 +0000)
(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.

gdb/ChangeLog
gdb/breakpoint.c
gdb/breakpoint.h
gdb/cli/cli-script.c
gdb/defs.h

index a21ec4a25ee3194c628f18e58466f8016d15a287..a6ef394d30e586ef0cb2ee88e8218dc02a01090d 100644 (file)
@@ -1,3 +1,28 @@
+2007-01-27  Eli Zaretskii  <eliz@gnu.org>
+
+       * 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  <brobecker@adacore.com>
 
        * ada-lang.c (ada_exception_breakpoint_ops): Fix typo in function name.
index 2a5e81f7764f6fdb3a52744d2ed3c4f2712061d3..e50c99a1f9b93d9a786ca8b9f692f41ea79ba322 100644 (file)
@@ -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);
+}
 \f
 /* Like target_read_memory() but if breakpoints are inserted, return
    the shadow contents instead of the breakpoints themselves.
index 79f1c1fcaf021f30c9247fd59975a8fc9b30e933..9eebfc8761d87ba4fffe508d691a2782ba098e47 100644 (file)
@@ -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);
 
index a27e971c0179a5693d0d5dbb2692109037350ec5..ad64a4a65b18e8b83e4b15dd364b7aa0401e86e7 100644 (file)
@@ -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);
index c7e6d3a51be4964ed59cc95af50f619648e261a3..beb1a3b2ac60985b084c87d50fea9046af9e20c9 100644 (file)
@@ -691,6 +691,7 @@ enum command_control_type
     continue_control,
     while_control,
     if_control,
+    commands_control,
     invalid_control
   };