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 [EMAIL PROTECTED] 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 _______________________________________________ Bug-gdb mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-gdb