This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Steven's hookpost patch finally in.


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. */
!         }
      }
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]