/* GDB CLI command scripting.
- Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006
+ Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GDB.
#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"
static void validate_comname (char *);
-/* Level of control structure. */
+/* Level of control structure when reading. */
static int control_level;
+/* Level of control structure when executing. */
+static int command_nest_depth = 1;
+
+/* This is to prevent certain commands being printed twice. */
+static int suppress_next_print_command_trace = 0;
+
/* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10
struct user_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));
/* 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;
}
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) */
not confused with Insight. */
in_user_command = 1;
+ command_nest_depth++;
while (cmdlines)
{
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;
}
+ command_nest_depth--;
do_cleanups (old_chain);
}
+/* This function is called every time GDB prints a prompt.
+ It ensures that errors and the like to not confuse the command tracing. */
+
+void
+reset_command_nest_depth (void)
+{
+ command_nest_depth = 1;
+
+ /* Just in case. */
+ suppress_next_print_command_trace = 0;
+}
+
+/* Print the command, prefixed with '+' to represent the call depth.
+ This is slightly complicated because this function may be called
+ from execute_command and execute_control_command. Unfortunately
+ execute_command also prints the top level control commands.
+ In these cases execute_command will call execute_control_command
+ via while_command or if_command. Inner levels of 'if' and 'while'
+ are dealt with directly. Therefore we can use these functions
+ to determine whether the command has been printed already or not. */
+void
+print_command_trace (const char *cmd)
+{
+ int i;
+
+ if (suppress_next_print_command_trace)
+ {
+ suppress_next_print_command_trace = 0;
+ return;
+ }
+
+ if (!source_verbose && !trace_commands)
+ return;
+
+ for (i=0; i < command_nest_depth; i++)
+ printf_filtered ("+");
+
+ printf_filtered ("%s\n", cmd);
+}
+
enum command_control_type
execute_control_command (struct command_line *cmd)
{
break;
case continue_control:
+ print_command_trace ("loop_continue");
+
+ /* Return for "continue", and "break" so we can either
+ continue the loop at the top, or break out. */
+ ret = cmd->control_type;
+ break;
+
case break_control:
+ print_command_trace ("loop_break");
+
/* Return for "continue", and "break" so we can either
continue the loop at the top, or break out. */
ret = cmd->control_type;
case while_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 7);
+ sprintf (buffer, "while %s", cmd->line);
+ print_command_trace (buffer);
+
/* Parse the loop control expression for the while statement. */
new_line = insert_args (cmd->line);
if (!new_line)
current = *cmd->body_list;
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, or a "break" command, then stop
looping. */
case if_control:
{
+ char *buffer = alloca (strlen (cmd->line) + 4);
+ sprintf (buffer, "if %s", cmd->line);
+ print_command_trace (buffer);
+
new_line = insert_args (cmd->line);
if (!new_line)
break;
/* Execute commands in the given arm. */
while (current)
{
+ command_nest_depth++;
ret = execute_control_command (current);
+ command_nest_depth--;
/* If we got an error, get out. */
if (ret != simple_control)
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;
}
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&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 *)
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;
}
/* 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);
}
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);