This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Steven's hookpost patch finally in.
- To: gdb-patches at sources dot redhat dot com
- Subject: Steven's hookpost patch finally in.
- From: Fernando Nasser <fnasser at cygnus dot com>
- Date: Sat, 28 Oct 2000 17:25:27 +0000
- Organization: Red Hat Canada Ltd. - Toronto
I finally checked Steven's changes in. I had to make a few changes to the
code to make it conform to the gdb current coding practices. I have also fixed
the ChangeLog entries.
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 initialization 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.
P.S.: If you wonder why I did this fixes myself and did not send the patch back
for rework by the originator as it the normal practice demands there is a
simple explanation: Steven has spent a long time helping me track and fix
some bugs in Insight, so it is my turn to give him a hand.
I am also using it to give him an example of how things should look like.
Don't expect such lenience unless you have also collected that
many brownie points :-)
--
Fernando Nasser
Red Hat Canada Ltd. E-Mail: fnasser@redhat.com
2323 Yonge Street, Suite #300
Toronto, Ontario M4P 2C9
===================================================================
RCS file: /cvs/src/src/gdb/command.h,v
retrieving revision 1.12
diff -c -p -r1.12 command.h
*** command.h 2000/06/23 08:12:27 1.12
--- command.h 2000/10/28 17:09:56
*************** struct cmd_list_element
*** 165,172 ****
char *replacement;
/* Hook for another command to be executed before this command. */
! struct cmd_list_element *hook;
/* Nonzero identifies a prefix command. For them, the address
of the variable containing the list of subcommands. */
struct cmd_list_element **prefixlist;
--- 165,179 ----
char *replacement;
/* Hook for another command to be executed before this command. */
! 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. */
struct cmd_list_element **prefixlist;
*************** struct cmd_list_element
*** 219,228 ****
/* Pointer to command strings of user-defined commands */
struct command_line *user_commands;
! /* Pointer to command that is hooked by this one,
so the hook can be removed when this one is deleted. */
! struct cmd_list_element *hookee;
/* Pointer to command that is aliased by this one, so the
aliased command can be located in case it has been hooked. */
--- 226,239 ----
/* Pointer to command strings of user-defined commands */
struct command_line *user_commands;
+
+ /* 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_post;
/* Pointer to command that is aliased by this one, so the
aliased command can be located in case it has been hooked. */
Index: command.c
===================================================================
RCS file: /cvs/src/src/gdb/command.c,v
retrieving revision 1.18
diff -c -p -r1.18 command.c
*** command.c 2000/10/23 22:49:28 1.18
--- command.c 2000/10/28 17:09:56
*************** add_cmd (char *name, enum command_class
*** 112,118 ****
c->doc = doc;
c->flags = 0;
c->replacement = NULL;
! c->hook = NULL;
c->prefixlist = NULL;
c->prefixname = NULL;
c->allow_unknown = 0;
--- 112,120 ----
c->doc = doc;
c->flags = 0;
c->replacement = NULL;
! c->hook_pre = NULL;
! c->hook_post = NULL;
! c->hook_in = 0;
c->prefixlist = NULL;
c->prefixname = NULL;
c->allow_unknown = 0;
*************** add_cmd (char *name, enum command_class
*** 123,129 ****
c->var_type = var_boolean;
c->enums = NULL;
c->user_commands = NULL;
! c->hookee = NULL;
c->cmd_pointer = NULL;
return c;
--- 125,132 ----
c->var_type = var_boolean;
c->enums = NULL;
c->user_commands = NULL;
! c->hookee_pre = NULL;
! c->hookee_post = NULL;
c->cmd_pointer = NULL;
return c;
*************** delete_cmd (char *name, struct cmd_list_
*** 366,373 ****
while (*list && STREQ ((*list)->name, name))
{
! if ((*list)->hookee)
! (*list)->hookee->hook = 0; /* Hook slips out of its mouth */
p = (*list)->next;
free ((PTR) * list);
*list = p;
--- 369,378 ----
while (*list && STREQ ((*list)->name, name))
{
! 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;
*************** delete_cmd (char *name, struct cmd_list_
*** 378,385 ****
{
if (STREQ (c->next->name, name))
{
! if (c->next->hookee)
! c->next->hookee->hook = 0; /* hooked cmd gets away. */
p = c->next->next;
free ((PTR) c->next);
c->next = p;
--- 383,393 ----
{
if (STREQ (c->next->name, name))
{
! 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;
*************** help_cmd (char *command, struct ui_file
*** 531,539 ****
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);
}
/*
--- 539,556 ----
if (c->function.cfunc == NULL)
help_list (cmdlist, "", c->class, stream);
! 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);
}
/*
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.18
diff -c -p -r1.18 infrun.c
*** infrun.c 2000/09/02 00:08:05 1.18
--- infrun.c 2000/10/28 17:09:58
*************** and/or watchpoints.\n");
*** 3446,3454 ****
/* Look up the hook_stop and run it if it exists. */
! if (stop_command && stop_command->hook)
{
! catch_errors (hook_stop_stub, stop_command->hook,
"Error while running hook_stop:\n", RETURN_MASK_ALL);
}
--- 3446,3454 ----
/* Look up the hook_stop and run it if it exists. */
! if (stop_command && stop_command->hook_pre)
{
! catch_errors (hook_stop_stub, stop_command->hook_pre,
"Error while running hook_stop:\n", RETURN_MASK_ALL);
}
Index: top.c
===================================================================
RCS file: /cvs/src/src/gdb/top.c,v
retrieving revision 1.18
diff -c -p -r1.18 top.c
*** top.c 2000/10/23 22:49:28 1.18
--- top.c 2000/10/28 17:09:59
*************** extern void serial_log_command (const ch
*** 1500,1508 ****
*(p + 1) = '\0';
}
! /* If this command has been hooked, run the hook first. */
! if (c->hook)
! execute_user_command (c->hook, (char *) 0);
if (c->flags & DEPRECATED_WARN_USER)
deprecated_cmd_warning (&line);
--- 1500,1512 ----
*(p + 1) = '\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);
*************** extern void serial_log_command (const ch
*** 1517,1522 ****
--- 1521,1535 ----
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). */
*************** user_defined_command (char *ignore, int
*** 2994,3005 ****
static void
define_command (char *comname, int from_tty)
{
register struct command_line *cmds;
! register struct cmd_list_element *c, *newc, *hookc = 0;
char *tem = comname;
! char tmpbuf[128];
#define HOOK_STRING "hook-"
#define HOOK_LEN 5
validate_comname (comname);
--- 3007,3031 ----
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, *oldc, *hookc = 0;
char *tem = comname;
! 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);
*************** define_command (char *comname, int from_
*** 3024,3033 ****
if (!strncmp (comname, HOOK_STRING, HOOK_LEN))
{
/* Look up cmd it hooks, and verify that we got an exact match. */
! tem = comname + HOOK_LEN;
hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
! if (hookc && !STREQ (comname + HOOK_LEN, hookc->name))
hookc = 0;
if (!hookc)
{
--- 3050,3070 ----
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_name_size;
hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
! if (hookc && !STREQ (comname + hook_name_size, hookc->name))
hookc = 0;
if (!hookc)
{
*************** define_command (char *comname, int from_
*** 3061,3068 ****
tied. */
if (hookc)
{
! hookc->hook = newc; /* Target gets hooked. */
! newc->hookee = hookc; /* We are marked as hooking target cmd. */
}
}
--- 3098,3116 ----
tied. */
if (hookc)
{
! 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. */
! }
}
}