/* GDB CLI command scripting.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+ Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+ 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+ Foundation, Inc.
This file is part of GDB.
#include "language.h" /* For value_true */
#include <ctype.h>
-#ifdef UI_OUT
#include "ui-out.h"
-#endif
+#include "gdb_string.h"
#include "top.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-script.h"
-/* From gdb/top.c */
-
-extern void dont_repeat (void);
-
-extern void do_restore_instream_cleanup (void *stream);
-
/* Prototypes for local functions */
static struct cleanup *
}
/* Recursively print a command (including full control structures). */
-#ifdef UI_OUT
+
void
print_command_lines (struct ui_out *uiout, struct command_line *cmd,
unsigned int depth)
/* A while command. Recursively print its subcommands and continue. */
if (list->control_type == while_control)
{
- ui_out_text (uiout, "while ");
ui_out_field_fmt (uiout, NULL, "while %s", list->line);
ui_out_text (uiout, "\n");
print_command_lines (uiout, *list->body_list, depth + 1);
- ui_out_field_string (uiout, NULL, "end");
if (depth)
ui_out_spaces (uiout, 2 * depth);
- ui_out_text (uiout, "end\n");
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
list = list->next;
continue;
}
/* An if command. Recursively print both arms before continueing. */
if (list->control_type == if_control)
{
- ui_out_text (uiout, "if ");
ui_out_field_fmt (uiout, NULL, "if %s", list->line);
ui_out_text (uiout, "\n");
/* The true arm. */
if (depth)
ui_out_spaces (uiout, 2 * depth);
ui_out_field_string (uiout, NULL, "else");
- ui_out_text (uiout, "else\n");
+ ui_out_text (uiout, "\n");
print_command_lines (uiout, list->body_list[1], depth + 1);
}
- ui_out_field_string (uiout, NULL, "end");
if (depth)
ui_out_spaces (uiout, 2 * depth);
- ui_out_text (uiout, "end\n");
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
list = list->next;
continue;
}
list = list->next;
} /* while (list) */
}
-#else
-void
-print_command_line (struct command_line *cmd, unsigned int depth,
- struct ui_file *stream)
-{
- unsigned int i;
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
-
- /* A simple command, print it and return. */
- if (cmd->control_type == simple_control)
- {
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- return;
- }
+/* Handle pre-post hooks. */
- /* loop_continue to jump to the start of a while loop, print it
- and return. */
- if (cmd->control_type == continue_control)
- {
- fputs_filtered ("loop_continue\n", stream);
- return;
- }
+static void
+clear_hook_in_cleanup (void *data)
+{
+ struct cmd_list_element *c = data;
+ c->hook_in = 0; /* Allow hook to work again once it is complete */
+}
- /* loop_break to break out of a while loop, print it and return. */
- if (cmd->control_type == break_control)
+void
+execute_cmd_pre_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_pre) && (!c->hook_in))
{
- fputs_filtered ("loop_break\n", stream);
- return;
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_pre, (char *) 0);
+ do_cleanups (cleanups);
}
+}
- /* A while command. Recursively print its subcommands before returning. */
- if (cmd->control_type == while_control)
+void
+execute_cmd_post_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_post) && (!c->hook_in))
{
- struct command_line *list;
- fputs_filtered ("while ", stream);
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- list = *cmd->body_list;
- while (list)
- {
- print_command_line (list, depth + 1, stream);
- list = list->next;
- }
- }
-
- /* An if command. Recursively print both arms before returning. */
- if (cmd->control_type == if_control)
- {
- fputs_filtered ("if ", stream);
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- /* The true arm. */
- print_command_line (cmd->body_list[0], depth + 1, stream);
-
- /* Show the false arm if it exists. */
- if (cmd->body_count == 2)
- {
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
- fputs_filtered ("else\n", stream);
- print_command_line (cmd->body_list[1], depth + 1, stream);
- }
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
- fputs_filtered ("end\n", stream);
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_post, (char *) 0);
+ do_cleanups (cleanups);
}
}
-#endif
/* Execute the command in CMD. */
+static void
+do_restore_user_call_depth (void * call_depth)
+{
+ int * depth = call_depth;
+ /* We will be returning_to_top_level() at this point, so we want to
+ reset our depth. */
+ (*depth) = 0;
+}
+
void
execute_user_command (struct cmd_list_element *c, char *args)
register struct command_line *cmdlines;
struct cleanup *old_chain;
enum command_control_type ret;
+ static int user_call_depth = 0;
+ extern int max_user_call_depth;
old_chain = setup_user_args (args);
/* Null command */
return;
+ if (++user_call_depth > max_user_call_depth)
+ error ("Max user call depth exceeded -- command aborted\n");
+
+ old_chain = make_cleanup (do_restore_user_call_depth, &user_call_depth);
+
/* Set the instream to 0, indicating execution of a
user-defined function. */
old_chain = make_cleanup (do_restore_instream_cleanup, instream);
cmdlines = cmdlines->next;
}
do_cleanups (old_chain);
+
+ user_call_depth--;
}
enum command_control_type
struct expression *expr;
struct command_line *current;
struct cleanup *old_chain = 0;
- value_ptr val;
- value_ptr val_mark;
+ struct value *val;
+ struct value *val_mark;
int loop;
enum command_control_type ret;
char *new_line;
xfree (l);
l = next;
}
+ *lptr = NULL;
}
static void
{
return make_cleanup (do_free_command_lines_cleanup, arg);
}
+
+struct command_line *
+copy_command_lines (struct command_line *cmds)
+{
+ struct command_line *result = NULL;
+
+ if (cmds)
+ {
+ result = (struct command_line *) xmalloc (sizeof (struct command_line));
+
+ result->next = copy_command_lines (cmds->next);
+ result->line = xstrdup (cmds->line);
+ result->control_type = cmds->control_type;
+ result->body_count = cmds->body_count;
+ if (cmds->body_count > 0)
+ {
+ int i;
+
+ result->body_list = (struct command_line **)
+ xmalloc (sizeof (struct command_line *) * cmds->body_count);
+
+ for (i = 0; i < cmds->body_count; i++)
+ result->body_list[i] = copy_command_lines (cmds->body_list[i]);
+ }
+ else
+ result->body_list = NULL;
+ }
+
+ return result;
+}
\f
static void
validate_comname (char *comname)
/* Look it up, and verify that we got an exact match. */
c = lookup_cmd (&tem, cmdlist, "", -1, 1);
- if (c && !STREQ (comname, c->name))
+ if (c && strcmp (comname, c->name) != 0)
c = 0;
if (c)
/* Look up cmd it hooks, and verify that we got an exact match. */
tem = comname + hook_name_size;
hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
- if (hookc && !STREQ (comname + hook_name_size, hookc->name))
+ if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
hookc = 0;
if (!hookc)
{
newc->hookee_pre = hookc; /* We are marked as hooking target cmd. */
break;
case CMD_POST_HOOK:
- hookc->hook_pre = newc; /* Target gets hooked. */
- newc->hookee_pre = hookc; /* We are marked as hooking target cmd. */
+ hookc->hook_post = newc; /* Target gets hooked. */
+ newc->hookee_post = hookc; /* We are marked as hooking target cmd. */
break;
default:
/* Should never come here as hookc would be 0. */
};
static void
-source_cleanup_lines (PTR args)
+source_cleanup_lines (void *args)
{
struct source_cleanup_lines_args *p =
(struct source_cleanup_lines_args *) args;
fputs_filtered (c->name, stream);
fputs_filtered (":\n", stream);
-#ifdef UI_OUT
print_command_lines (uiout, cmdlines, 1);
fputs_filtered ("\n", stream);
-#else
- while (cmdlines)
- {
- print_command_line (cmdlines, 4, stream);
- cmdlines = cmdlines->next;
- }
- fputs_filtered ("\n", stream);
-#endif
}