+2000-11-06 Fernando Nasser <fnasser@cygnus.com>
+
+ From Steven Johnson <sbjohnson@ozemail.com.au>:
+
+ This set of changes add "hookpost-" as an expansion on the original
+ hooking of commands to GDB. A Hook may now be run "AFTER" execution of
+ a command as well as before.
+
+ * command.h (struct cmd_list_element): Changed elements hook and hookee
+ to hook_pre and hookee_pre respectively. Added hook_post and hookee_post
+ for the post hook command operation. Added hook_in so that an executing
+ hook can be flagged to prevent recursion.
+ * command.c (add_cmd): Changed initilization of cmd_list_element to
+ reflect above changes.
+ (delete_cmd): Remove both pre and post hooks.
+ (help_cmd): Notify that the command has pre and/or post hooks.
+ * infrun.c (normal_stop): Change references to hook_pre from hook.
+ * top.c (execute_command): Run both pre and post hooks.
+ (define_command): Allow definition of both pre and post hooks.
+ The definition of pre-hooks is done as before, with the "hook-"
+ prefix for backward compatibility.
+
2000-11-06 Peter Schauer <pes@regent.e-technik.tu-muenchen.de>
* stack.c (return_command): Pop dummy frame if we just returned from
c->doc = doc;
c->flags = 0;
c->replacement = NULL;
- c->hook = NULL;
+ c->hook_pre = NULL;
+ c->hook_post = NULL;
+ c->hook_in = 0;
c->prefixlist = NULL;
c->prefixname = NULL;
c->allow_unknown = 0;
c->var_type = var_boolean;
c->enums = NULL;
c->user_commands = NULL;
- c->hookee = NULL;
+ c->hookee_pre = NULL;
+ c->hookee_post = NULL;
c->cmd_pointer = NULL;
return c;
while (*list && STREQ ((*list)->name, name))
{
- if ((*list)->hookee)
- (*list)->hookee->hook = 0; /* Hook slips out of its mouth */
+ if ((*list)->hookee_pre)
+ (*list)->hookee_pre->hook_pre = 0; /* Hook slips out of its mouth */
+ if ((*list)->hookee_post)
+ (*list)->hookee_post->hook_post = 0; /* Hook slips out of its bottom */
p = (*list)->next;
free ((PTR) * list);
*list = p;
{
if (STREQ (c->next->name, name))
{
- if (c->next->hookee)
- c->next->hookee->hook = 0; /* hooked cmd gets away. */
+ if (c->next->hookee_pre)
+ c->next->hookee_pre->hook_pre = 0; /* hooked cmd gets away. */
+ if (c->next->hookee_post)
+ c->next->hookee_post->hook_post = 0; /* remove post hook */
+ /* :( no fishing metaphore */
p = c->next->next;
free ((PTR) c->next);
c->next = p;
if (c->function.cfunc == NULL)
help_list (cmdlist, "", c->class, stream);
- if (c->hook)
- fprintf_filtered (stream, "\nThis command has a hook defined: %s\n",
- c->hook->name);
+ if (c->hook_pre || c->hook_post)
+ fprintf_filtered (stream,
+ "\nThis command has a hook (or hooks) defined:\n");
+
+ if (c->hook_pre)
+ fprintf_filtered (stream,
+ "\tThis command is run after : %s (pre hook)\n",
+ c->hook_pre->name);
+ if (c->hook_post)
+ fprintf_filtered (stream,
+ "\tThis command is run before : %s (post hook)\n",
+ c->hook_post->name);
}
/*
char *replacement;
/* Hook for another command to be executed before this command. */
- struct cmd_list_element *hook;
+ struct cmd_list_element *hook_pre;
+
+ /* Hook for another command to be executed after this command. */
+ struct cmd_list_element *hook_post;
+
+ /* Flag that specifies if this command is already running it's hook. */
+ /* Prevents the possibility of hook recursion. */
+ int hook_in;
/* Nonzero identifies a prefix command. For them, the address
of the variable containing the list of subcommands. */
/* Pointer to command strings of user-defined commands */
struct command_line *user_commands;
- /* Pointer to command that is hooked by this one,
+ /* Pointer to command that is hooked by this one, (by hook_pre)
+ so the hook can be removed when this one is deleted. */
+ struct cmd_list_element *hookee_pre;
+
+ /* Pointer to command that is hooked by this one, (by hook_post)
so the hook can be removed when this one is deleted. */
- struct cmd_list_element *hookee;
+ struct cmd_list_element *hookee_post;
/* Pointer to command that is aliased by this one, so the
aliased command can be located in case it has been hooked. */
/* Look up the hook_stop and run it if it exists. */
- if (stop_command && stop_command->hook)
+ if (stop_command && stop_command->hook_pre)
{
- catch_errors (hook_stop_stub, stop_command->hook,
+ catch_errors (hook_stop_stub, stop_command->hook_pre,
"Error while running hook_stop:\n", RETURN_MASK_ALL);
}
*(p + 1) = '\0';
}
- /* If this command has been hooked, run the hook first. */
- if (c->hook)
- execute_user_command (c->hook, (char *) 0);
+ /* If this command has been pre-hooked, run the hook first. */
+ if ((c->hook_pre) && (!c->hook_in))
+ {
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_pre, (char *) 0);
+ c->hook_in = 0; /* Allow hook to work again once it is complete */
+ }
if (c->flags & DEPRECATED_WARN_USER)
deprecated_cmd_warning (&line);
call_command_hook (c, arg, from_tty & caution);
else
(*c->function.cfunc) (arg, from_tty & caution);
+
+ /* If this command has been post-hooked, run the hook last. */
+ if ((c->hook_post) && (!c->hook_in))
+ {
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_post, (char *) 0);
+ c->hook_in = 0; /* allow hook to work again once it is complete */
+ }
+
}
/* Tell the user if the language has changed (except first time). */
static void
define_command (char *comname, int from_tty)
{
+#define MAX_TMPBUF 128
+ enum cmd_hook_type
+ {
+ CMD_NO_HOOK = 0,
+ CMD_PRE_HOOK,
+ CMD_POST_HOOK
+ };
register struct command_line *cmds;
- register struct cmd_list_element *c, *newc, *hookc = 0;
+ register struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
char *tem = comname;
- char tmpbuf[128];
+ char *tem2;
+ char tmpbuf[MAX_TMPBUF];
+ int hook_type = CMD_NO_HOOK;
+ int hook_name_size = 0;
+
#define HOOK_STRING "hook-"
#define HOOK_LEN 5
+#define HOOK_POST_STRING "hookpost-"
+#define HOOK_POST_LEN 9
validate_comname (comname);
we can hook the `stop' pseudo-command. */
if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
+ {
+ hook_type = CMD_PRE_HOOK;
+ hook_name_size = HOOK_LEN;
+ }
+ else if (!strncmp (comname, HOOK_POST_STRING, HOOK_POST_LEN))
+ {
+ hook_type = CMD_POST_HOOK;
+ hook_name_size = HOOK_POST_LEN;
+ }
+
+ if (hook_type != CMD_NO_HOOK)
{
/* Look up cmd it hooks, and verify that we got an exact match. */
- tem = comname + HOOK_LEN;
+ tem = comname + hook_name_size;
hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
- if (hookc && !STREQ (comname + HOOK_LEN, hookc->name))
+ if (hookc && !STREQ (comname + hook_name_size, hookc->name))
hookc = 0;
if (!hookc)
{
tied. */
if (hookc)
{
- hookc->hook = newc; /* Target gets hooked. */
- newc->hookee = hookc; /* We are marked as hooking target cmd. */
+ switch (hook_type)
+ {
+ case CMD_PRE_HOOK:
+ hookc->hook_pre = newc; /* Target gets hooked. */
+ 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. */
+ break;
+ default:
+ /* Should never come here as hookc would be 0. */
+ }
}
}