From 73bc900df9bcfe3ce24453219d2303fafb1395de Mon Sep 17 00:00:00 2001 From: Fernando Nasser Date: Mon, 6 Nov 2000 22:44:34 +0000 Subject: [PATCH] 2000-11-06 Fernando Nasser From Steven Johnson : 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. --- gdb/ChangeLog | 22 +++++++++++++++++ gdb/command.c | 35 ++++++++++++++++++++------- gdb/command.h | 17 ++++++++++--- gdb/infrun.c | 4 ++-- gdb/top.c | 66 ++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 121 insertions(+), 23 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 264e7441086..d0ad9b98750 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,25 @@ +2000-11-06 Fernando Nasser + + From Steven Johnson : + + 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 * stack.c (return_command): Pop dummy frame if we just returned from diff --git a/gdb/command.c b/gdb/command.c index 3b59d33ae9f..6e64de42f71 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -112,7 +112,9 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int), 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; @@ -123,7 +125,8 @@ add_cmd (char *name, enum command_class class, void (*fun) (char *, int), 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; @@ -366,8 +369,10 @@ delete_cmd (char *name, struct cmd_list_element **list) 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; @@ -378,8 +383,11 @@ delete_cmd (char *name, struct cmd_list_element **list) { 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; @@ -531,9 +539,18 @@ help_cmd (char *command, struct ui_file *stream) 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); } /* diff --git a/gdb/command.h b/gdb/command.h index bbafe1bc648..ab678a23152 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -165,7 +165,14 @@ struct cmd_list_element 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. */ @@ -220,9 +227,13 @@ struct cmd_list_element /* 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. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index c3cf023851e..57233a8f1b8 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3446,9 +3446,9 @@ and/or watchpoints.\n"); /* 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); } diff --git a/gdb/top.c b/gdb/top.c index c921407b6ee..7bc55620b7f 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1500,9 +1500,13 @@ extern void serial_log_command (const char *); *(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); @@ -1517,6 +1521,15 @@ extern void serial_log_command (const char *); 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). */ @@ -2988,12 +3001,25 @@ user_defined_command (char *ignore, int from_tty) 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); @@ -3017,11 +3043,22 @@ define_command (char *comname, int from_tty) 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) { @@ -3055,8 +3092,19 @@ define_command (char *comname, int from_tty) 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. */ + } } } -- 2.30.2