bug-gdb
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

small enhancements to gdb here..


From: Don Beusee
Subject: small enhancements to gdb here..
Date: Mon, 20 Nov 2000 17:22:01 -0800 (PST)

Hi,

I have patches for 3 enhancements:

- allow O/S commands directly from gdb when no match for internal command.
- better arg syntax in user-defined commands:
    $#        number of args
    $*        all args
    $N        specific arg (where N is a number from 1 to 9).  $1 is the first
              arg (same as $arg0).
    ${NN}     NN can be any number between 1 and MAXUSERARGS (10).
    ${ENV}    environment variable
- a user command referencing an argument not provided on the command returns
  an empty string, not an error.

Example .gdbinit:
define sh
   shell $*
end
define host
   shell $*
end
define pa
   echo args = $*, count = $#\n
   echo arg1 = $1\n
   echo arg2 = $2\n
   echo arg10 = ${10}\n
   echo arg0=$arg0\n
   echo arg1=$arg1\n
end
define c
   if strcmp("$1", "at") == 0
      printf "continuing at %d\n", $2
      jump $2
   else
      continue $*
   end
end

Here are the patches for command.c and top.c:

$ rcsdiff -c command.c
*** 1.1 2000/11/20 11:49:09
--- command.c   2000/11/20 11:53:35
***************
*** 43,49 ****
  
  static void make_command PARAMS ((char *, int));
  
! static void shell_escape PARAMS ((char *, int));
  
  static int parse_binary_operation PARAMS ((char *));
  
--- 43,49 ----
  
  static void make_command PARAMS ((char *, int));
  
! void shell_escape PARAMS ((char *, int));
  
  static int parse_binary_operation PARAMS ((char *));
  
***************
*** 512,518 ****
  
    c = lookup_cmd (&command, cmdlist, "", 0, 0);
  
!   if (c == 0)
      return;
  
    /* There are three cases here.
--- 512,518 ----
  
    c = lookup_cmd (&command, cmdlist, "", 0, 0);
  
!   if (c == 0 || c == -1 || c == -2)
      return;
  
    /* There are three cases here.
***************
*** 901,908 ****
     LIST is a chain of struct cmd_list_element's.
     If it is found, return the struct cmd_list_element for that command
     and update *LINE to point after the command name, at the first argument.
!    If not found, call error if ALLOW_UNKNOWN is zero
!    otherwise (or if error returns) return zero.
     Call error if specified command is ambiguous,
     unless ALLOW_UNKNOWN is negative.
     CMDTYPE precedes the word "command" in the error message.
--- 901,908 ----
     LIST is a chain of struct cmd_list_element's.
     If it is found, return the struct cmd_list_element for that command
     and update *LINE to point after the command name, at the first argument.
!    If not found, return -2 to signal caller to run shell if ALLOW_UNKNOWN is
!    zero otherwise (or if error returns) return zero.
     Call error if specified command is ambiguous,
     unless ALLOW_UNKNOWN is negative.
     CMDTYPE precedes the word "command" in the error message.
***************
*** 948,954 ****
              q = (char *) alloca (p - *line + 1);
              strncpy (q, *line, p - *line);
              q[p - *line] = '\0';
!             undef_cmd_error (cmdtype, q);
            }
        }
        else
--- 948,957 ----
              q = (char *) alloca (p - *line + 1);
              strncpy (q, *line, p - *line);
              q[p - *line] = '\0';
!             if (!*cmdtype)
!                  return (struct cmd_list_element *) -2; /* invoke shell */
!               else
!                  undef_cmd_error (cmdtype, q);
            }
        }
        else
***************
*** 1861,1867 ****
  }
  
  /* ARGSUSED */
! static void
  shell_escape (arg, from_tty)
       char *arg;
       int from_tty;
--- 1864,1870 ----
  }
  
  /* ARGSUSED */
! void
  shell_escape (arg, from_tty)
       char *arg;
       int from_tty;


$ rcsdiff -c top.c
*** 1.1 2000/11/20 11:49:13
--- top.c       2000/11/20 12:02:39
***************
*** 97,103 ****
  
  static struct cleanup *setup_user_args PARAMS ((char *));
  
! static char *locate_arg PARAMS ((char *));
  
  static char *insert_args PARAMS ((char *));
  
--- 97,105 ----
  
  static struct cleanup *setup_user_args PARAMS ((char *));
  
! static char *locate_arg PARAMS ((char *, int *, char **, char **, char *));
! 
! static char *itoa PARAMS ((int));
  
  static char *insert_args PARAMS ((char *));
  
***************
*** 144,149 ****
--- 146,153 ----
  
  static void do_nothing PARAMS ((int));
  
+ extern void shell_escape PARAMS ((char *, int));
+ 
  static void show_debug PARAMS ((char *, int));
  
  static void set_debug PARAMS ((char *, int));
***************
*** 360,365 ****
--- 364,370 ----
        int len;
        }
      a[MAXUSERARGS];
+     char args[256];
      int count;
    }
   *user_args;
***************
*** 1296,1301 ****
--- 1301,1308 ----
    if (p == NULL)
      return old_chain;
  
+   strcpy(args->args, p);
+ 
    while (*p)
      {
        char *start_arg;
***************
*** 1357,1376 ****
    return old_chain;
  }
  
! /* Given character string P, return a point to the first argument ($arg),
!    or NULL if P contains no arguments.  */
  
  static char *
! locate_arg (p)
!      char *p;
  {
    while ((p = strchr (p, '$')))
      {
        if (strncmp (p, "$arg", 4) == 0 && isdigit (p[4]))
!       return p;
        p++;
      }
!   return NULL;
  }
  
  /* Insert the user defined arguments stored in user_arg into the $arg
--- 1364,1450 ----
    return old_chain;
  }
  
! /*
!  * Given character string P, return a point to the substitution argument
!  * or variable; or NULL if P contains no arguments or variable tokens.
!  * num will contain one of the following values:
!  *    -1 (all arguments should replace this token)
!  *    -2 (argument count should replace this token)
!  *    -3 (string stored in newstr should replace this token)
!  *    the argument number,
!  */
  
  static char *
! locate_arg (p, num, start, after, newstr)
!      char *p, **start, **after, *newstr;
!      int *num;
  {
+   *start = NULL;
+   *newstr = '\0';
    while ((p = strchr (p, '$')))
      {
        if (strncmp (p, "$arg", 4) == 0 && isdigit (p[4]))
!       {
!         *num = p[4]-'0';
!         *start = p;
!         *after = p+5;
!         return *start;
!       }
!       if (p[0] == '$' && isdigit (p[1]))
!       {
!         *num = p[1] - '0' - 1;
!         *start = p;
!         *after = p+2;
!         return *start;
!       }
!       if (p[0] == '$' && p[1] == '#')
!       {
!         *num = -2; /* indicates to replace with count */
!         *start = p;
!         *after = p+2;
!         return *start;
!       }
!       if (p[0] == '$' && p[1] == '*')
!       {
!         *num = -1; /* indicates to use all args */
!         *start = p;
!         *after = p+2;
!         return *start;
!       }
!       if (p[0] == '$' && p[1] == '{' && isdigit(p[2]))
!       {
!         *num = atoi(p+2) - 1;
!         *start = p;
!         *after = strchr(p, '}')+1;
!         return *start;
!       }
!       if (p[0] == '$' && p[1] == '{')
!         {
!           char env[256], *e;
!           memset(env, '\0', sizeof(env));
!           *num = -3; /* environment variable */
!           *start = p;
!           *after = strchr(p, '}')+1;
!           memcpy(env, p+2, (*after) - p - 3);
!           if (e = getenv(env))
!             {
!               strcpy(newstr, e);
!             }
!           return *start;
!         }
        p++;
      }
!   return *start;
! }
! 
! static char *
! itoa(i)
!         int i;
! {
!         static char a[12];
!         *a = '\0';
!         sprintf(a, "%0d", i);
!         return(a);
  }
  
  /* Insert the user defined arguments stored in user_arg into the $arg
***************
*** 1380,1403 ****
  insert_args (line)
       char *line;
  {
!   char *p, *save_line, *new_line;
!   unsigned len, i;
  
    /* First we need to know how much memory to allocate for the new line.  */
    save_line = line;
    len = 0;
!   while ((p = locate_arg (line)))
      {
!       len += p - line;
!       i = p[4] - '0';
! 
!       if (i >= user_args->count)
!       {
!         error ("Missing argument %d in user function.\n", i);
!         return NULL;
        }
!       len += user_args->a[i].len;
!       line = p + 5;
      }
  
    /* Don't forget the tail.  */
--- 1454,1486 ----
  insert_args (line)
       char *line;
  {
!   char *p, *save_line, *new_line, *afterarg;
!   char envstr[256];
!   unsigned len;
!   int i;
  
    /* First we need to know how much memory to allocate for the new line.  */
    save_line = line;
    len = 0;
!   while (locate_arg (line, &i/*argnum*/, &p/*startarg*/, &afterarg, envstr))
      {
!       len += p - line; /* add portion before arg token */
!       if (i == -1 && user_args)
!         len += strlen(user_args->args);
!       else if (i == -2 && user_args)
!         len += strlen(itoa(user_args->count));
!       else if (i == -3)
!         len += strlen(envstr);
!       else if (user_args && i < user_args->count)
!         len += user_args->a[i].len;
! /*
!       else
!         {
!              error ("Missing argument %d in user function.\n", i);
!              return NULL;
        }
! */
!       line = afterarg;
      }
  
    /* Don't forget the tail.  */
***************
*** 1406,1412 ****
    /* Allocate space for the new line and fill it in.  */
    new_line = (char *) xmalloc (len + 1);
    if (new_line == NULL)
!     return NULL;
  
    /* Restore pointer to beginning of old line.  */
    line = save_line;
--- 1489,1498 ----
    /* Allocate space for the new line and fill it in.  */
    new_line = (char *) xmalloc (len + 1);
    if (new_line == NULL)
!     {
!       error ("could not allocate memory for argument substitution.\n");
!       return NULL;
!     }
  
    /* Restore pointer to beginning of old line.  */
    line = save_line;
***************
*** 1414,1434 ****
    /* Save pointer to beginning of new line.  */
    save_line = new_line;
  
!   while ((p = locate_arg (line)))
      {
!       int i, len;
! 
!       memcpy (new_line, line, p - line);
!       new_line += p - line;
!       i = p[4] - '0';
! 
!       len = user_args->a[i].len;
!       if (len)
!       {
          memcpy (new_line, user_args->a[i].arg, len);
!         new_line += len;
!       }
!       line = p + 5;
      }
    /* Don't forget the tail.  */
    strcpy (new_line, line);
--- 1500,1535 ----
    /* Save pointer to beginning of new line.  */
    save_line = new_line;
  
!   while (locate_arg (line, &i/*argnum*/, &p/*startarg*/, &afterarg, envstr))
      {
!       memcpy (new_line, line, p - line); /* copy line before arg token */
!       new_line += p - line; /* point new_line at end */
!       if (i == -1 && user_args)
!         {
!           len = strlen(user_args->args);
!         memcpy (new_line, user_args->args, len);
!         }
!       else if (i == -2 && user_args)
!         {
!           len = strlen(itoa(user_args->count));
!         memcpy (new_line, itoa(user_args->count), len);
!         }
!       else if (i == -3)
!         {
!           len = strlen(envstr);
!         memcpy (new_line, envstr, len);
!         }
!       else if (user_args && i < user_args->count)
!         {
!           len = user_args->a[i].len;
          memcpy (new_line, user_args->a[i].arg, len);
!         }
!       else
!         {
!         len = 0; /* arg not present - add nothing */
!         }
!       new_line += len;
!       line = afterarg;
      }
    /* Don't forget the tail.  */
    strcpy (new_line, line);
***************
*** 1505,1510 ****
--- 1606,1619 ----
        line = p;
  
        c = lookup_cmd (&p, cmdlist, "", 0, 1);
+       if (c == (struct cmd_list_element *)-2) /* invoke shell? */
+         {
+           char *shellcmd;
+           shellcmd = malloc(strlen(p)+7);
+           sprintf(shellcmd, "shell %s", p);
+           execute_command(shellcmd, from_tty);
+           return;
+         }
  
        /* If the target is running, we allow only a limited set of
           commands. */
***************
*** 1517,1522 ****
--- 1626,1635 ----
  
        /* Pass null arg rather than an empty one.  */
        arg = *p ? p : 0;
+       if (arg && c->function.cfunc != define_command
+               && c->function.cfunc != shell_escape   )
+          arg=insert_args(arg); /* replace environment variables in command 
with
+                                   their values */
  
        /* Clear off trailing whitespace, except for set and complete command.  
*/
        if (arg && c->type != set_cmd && c->function.cfunc != complete_command)

-Don

------------------------------------------------------------------------------
Don Beusee                                  address@hidden
Backup Restore Products
Server Technologies Division
Oracle Corporation
==============================================================================
HELPBKUP POSTERS: see note 69202.1 for tips on a complete post.
EBU 2.2.0.5 and below are no longer supported!  See our web site:
http://backup.us.oracle.com/ebu/ebu_y2k_comply.html





reply via email to

[Prev in Thread] Current Thread [Next in Thread]