Author: rgrjr
Date: Sat Jan 26 08:16:44 2008
New Revision: 25254

Modified:
   trunk/src/debug.c

Log:
* src/debug.c:
   + (parse_command):  Skip leading whitespace.  This fixes a bug in
     help, which didn't if given a command name.
   + (PDB_help):  Also skip leading WS to improve error messages, add
     expanded help for "print".
   + (GDB_print_reg):  Split out of GDB_P.
   + (GDB_P):  If nothing after the register type, print all such regs.
     Also, made the reg type case-insensitive.


Modified: trunk/src/debug.c
==============================================================================
--- trunk/src/debug.c   (original)
+++ trunk/src/debug.c   Sat Jan 26 08:16:44 2008
@@ -329,6 +329,10 @@
     int           i;
     unsigned long c = 0;
 
+    /* Skip leading whitespace. */
+    while (*command && isspace(*command))
+        command++;
+
     if (*command == '\0') {
         *cmdP = c;
         return NULL;
@@ -2491,9 +2495,11 @@
 PDB_help(PARROT_INTERP, ARGIN(const char *command))
 {
     unsigned long c;
-    const char   *temp = command;
 
-    command = parse_command(command, &c);
+    /* Extract the command after leading whitespace (for error messages). */
+    while (*command && isspace(*command))
+        command++;
+    (void) parse_command(command, &c);
 
     switch (c) {
         case c_disassemble:
@@ -2578,7 +2584,9 @@
 the -t option.\n");
             break;
         case c_print:
-            PIO_eprintf(interp, "Print register: e.g. p I2\n");
+            PIO_eprintf(interp, "Print register: e.g. \"p i2\"\n\
+Note that the register type is case-insensitive.  If no digits appear\n\
+after the register type, all registers of that type are printed.\n");
             break;
         case c_info:
             PIO_eprintf(interp,
@@ -2617,7 +2625,7 @@
 Type \"help\" followed by a command name for full documentation.\n\n");
             break;
         default:
-            PIO_eprintf(interp, "Unknown command: \"%s\".", temp);
+            PIO_eprintf(interp, "Unknown command: \"%s\".", command);
             break;
     }
 }
@@ -2717,20 +2725,8 @@
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
 static const char*
-GDB_P(PARROT_INTERP, ARGIN(const char *s))
+GDB_print_reg(PARROT_INTERP, ARGIN(int t), ARGIN(int n))
 {
-    int t, n;
-    switch (*s) {
-        case 'I': t = REGNO_INT; break;
-        case 'N': t = REGNO_NUM; break;
-        case 'S': t = REGNO_STR; break;
-        case 'P': t = REGNO_PMC; break;
-        default: return "no such reg";
-    }
-    if (s[1] && isdigit((unsigned char)s[1]))
-        n = atoi(s + 1);
-    else
-        return "no such reg";
 
     if (n >= 0 && n < CONTEXT(interp->ctx)->n_regs_used[t]) {
         switch (t) {
@@ -2751,6 +2747,47 @@
     return "no such reg";
 }
 
+PARROT_WARN_UNUSED_RESULT
+PARROT_CANNOT_RETURN_NULL
+static const char*
+GDB_P(PARROT_INTERP, ARGIN(const char *s))
+{
+    int t, n;
+    char reg_type;
+
+    /* Skip leading whitespace. */
+    while (*s && isspace(*s))
+        s++;
+
+    reg_type = (unsigned char) toupper(*s);
+    switch (reg_type) {
+        case 'I': t = REGNO_INT; break;
+        case 'N': t = REGNO_NUM; break;
+        case 'S': t = REGNO_STR; break;
+        case 'P': t = REGNO_PMC; break;
+        default: return "Need a register.";
+    }
+    if (! s[1]) {
+        /* Print all registers of this type. */
+        int max_reg = CONTEXT(interp->ctx)->n_regs_used[t];
+        int n;
+
+        for (n = 0; n < max_reg; n++) {
+            /* this must be done in two chunks because PMC's print directly. */
+            PIO_eprintf(interp, "\n  %c%d = ", reg_type, n);
+            PIO_eprintf(interp, "%s", GDB_print_reg(interp, t, n));
+        }
+        return "";
+    }
+    else if (s[1] && isdigit((unsigned char)s[1])) {
+        n = atoi(s + 1);
+        return GDB_print_reg(interp, t, n);
+    }
+    else
+        return "no such reg";
+
+}
+
 /* RT#46141 move these to debugger interpreter
  */
 static PDB_breakpoint_t *gdb_bps;

Reply via email to