2000-11-06 Fernando Nasser <fnasser@cygnus.com>
authorFernando Nasser <fnasser@redhat.com>
Mon, 6 Nov 2000 22:44:34 +0000 (22:44 +0000)
committerFernando Nasser <fnasser@redhat.com>
Mon, 6 Nov 2000 22:44:34 +0000 (22:44 +0000)
        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.

gdb/ChangeLog
gdb/command.c
gdb/command.h
gdb/infrun.c
gdb/top.c

index 264e744..d0ad9b9 100644 (file)
@@ -1,3 +1,25 @@
+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
index 3b59d33..6e64de4 100644 (file)
@@ -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);
 }
 
 /*
index bbafe1b..ab678a2 100644 (file)
@@ -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.  */
index c3cf023..57233a8 100644 (file)
@@ -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);
     }
 
index c921407..7bc5562 100644 (file)
--- 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);
 
@@ -3018,10 +3044,21 @@ define_command (char *comname, int from_tty)
 
   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. */
+        }
     }
 }