# New Ticket Created by  Steve Fink 
# Please include the string:  [perl #16767]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=16767 >


- eliminates a bunch of seg faults from bad input
- allow passing command-line arguments to the program
- allow printing indexed aggregates indexed by integers (eg 'p P0[0]')
  (other key types need implementing)
- makes pdb exit on EOF (ctrl-d on unix)
- removed some code duplication, other cleanups

CC'ing this to Daniel Grunblatt since it's his baby I'm molesting.


-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/35709/28946/2a6256/pdb.patch

Index: debug.c
===================================================================
RCS file: /cvs/public/parrot/debug.c,v
retrieving revision 1.29
diff -p -u -r1.29 debug.c
--- debug.c     25 Aug 2002 23:38:13 -0000      1.29
+++ debug.c     26 Aug 2002 02:33:42 -0000
@@ -29,6 +29,116 @@
     while(*c && isspace((int) *c)) \
         c++; }
 
+/* nextarg
+ *
+ * Returns the position just past the current argument in a PASM
+ * instruction. This is not the same as na(), above, which is intended
+ * for debugger commands. This function is used for eval. */
+static const char* nextarg(const char* command)
+{
+    while (*command && (isalnum((int) *command) || *command == ',' || *command == 
+']'))
+        command++;
+    while (*command && isspace((int) *command))
+        command++;
+    return command;
+}
+
+/* skip_ws
+ *
+ * Returns the pointer past any whitespace */
+static const char* skip_ws(const char* str)
+{
+    while (*str && isspace((int) *str)) str++;
+    return str;
+}
+
+/* skip_command
+ *
+ * Returns the pointer past the current debugger command. (This is an
+ * alternative to the na() macro above.) */
+static const char* skip_command(const char* str)
+{
+    while (*str && !isspace((int) *str)) str++;
+    while (*str && isspace((int) *str)) str++;
+    return str;
+}
+
+/* parse_int
+ *
+ * Parse an integer out of a string and return a pointer to just after
+ * the int. */
+static const char* parse_int(const char* str, int* intP)
+{
+    char* end;
+    *intP = strtol(str, &end, 0);
+    return end;
+}
+
+/* parse_string
+ *
+ * Parse a double-quoted string out of a C string and return a pointer
+ * to just after the string. The parsed string is converted to a
+ * Parrot STRING. */
+static const char* parse_string(struct Parrot_Interp *interpreter,
+                                const char* str, STRING** strP)
+{
+    const char* string;
+    if (*str != '"') return NULL;
+    str++;
+    string = str;
+    while (*str && *str != '"') {
+        if (*str == '\\' && str[1]) str += 2;
+        else str++;
+    }
+
+    *strP = string_make(interpreter, string, str - string, NULL, 0, NULL);
+    if (*str) str++;
+    return str;
+}
+
+/* parse_key
+ *
+ * Parse an aggregate key out of a string and return a pointer to just
+ * after the key. Currently only string and integer keys are
+ * allowed. */
+static const char* parse_key(struct Parrot_Interp *interpreter,
+                             const char* str, PMC** keyP)
+{
+    *keyP = NULL;
+    if (*str != '[') return NULL;
+    str++; /* Skip [ */
+    if (*str == '"') {
+        STRING* string;
+        str = parse_string(interpreter, str, &string);
+        *keyP = key_new_string(interpreter, string);
+    } else if (isdigit((int) *str)) {
+        int value;
+        str = parse_int(str, &value);
+        *keyP = key_new_integer(interpreter, (INTVAL) value);
+    } else {
+        return NULL;
+    }
+
+    if (*str != ']') return NULL;
+    return ++str;
+}
+
+/* parse_command
+ *
+ * Convert the command at the beginning of a string into a numeric
+ * value that can be used as a switch key for fast lookup. */
+static const char* parse_command(const char* command, unsigned long* cmdP)
+{
+    int i;
+    unsigned long c = 0;
+    if (*command == '\0') return 0;
+    for (i = 0; *command && isalpha((int) *command); command++, i++)
+        c += (tolower((int) *command) + (i + 1)) * ((i + 1) * 255);
+    if (c == 0) c = -1; /* Nonempty and did not start with a letter */
+    *cmdP = c;
+    return command;
+}
+
 /* PDB_get_command(struct Parrot_Interp *interpreter)
  *
  * Get a command from the user input to execute.
@@ -49,6 +159,7 @@ PDB_get_command(struct Parrot_Interp *in
     char *c;
     PDB_t *pdb = interpreter->pdb;
     PDB_line_t *line; 
+    int ch;
 
     /* flush the buffered data */
     fflush(stdout);
@@ -81,13 +192,14 @@ PDB_get_command(struct Parrot_Interp *in
 
     fprintf(stderr,"\n(pdb) ");
 
-    *c = (char)fgetc(stdin);
-
-    while ((c[i - 1] !=  '\n') && (i < 255))
-        c[i++] = (char)fgetc(stdin);
+    *c = (char)(ch = fgetc(stdin));
 
-    c[--i] = '\0';
+    while (ch != -1 && (c[i - 1] !=  '\n') && (i < 255))
+        c[i++] = (char)(ch = fgetc(stdin));
     
+    c[--i] = '\0';
+
+    if (ch == -1) strcpy(c, "quit");
     pdb->cur_command = c;
 }
         
@@ -102,82 +214,81 @@ PDB_run_command(struct Parrot_Interp *in
 {
     PDB_t *pdb = interpreter->pdb;
     int i;
-    unsigned long c = 0;
+    unsigned long c;
 
     /* Skip trailing spaces */
-    while (*command && isspace((int) *command))
-        command++;
+    command = skip_ws(command);
+
     /* get a number from what the user typed */
-    for (i = 0; ((command[i] != 32) && command[i]) ; i++)
-        c += (command[i] + (i + 1)) * ((i + 1) * 255);
+    command = parse_command(command, &c);
 
     switch (c) {
         case c_disassemble:
-            na(command);
+            command = skip_command(command);
             PDB_disassemble(interpreter,command);
             break;
         case c_load:
-            na(command);
+            command = skip_command(command);
             PDB_load_source(interpreter,command);
             break;
         case c_l:
         case c_list:
-            na(command);
+            command = skip_command(command);
             PDB_list(interpreter,command);
             break;
         case c_b:
         case c_break:
-            na(command);
+            command = skip_command(command);
             PDB_set_break(interpreter,command);
             break;
         case c_d:
         case c_delete:
-            na(command);
+            command = skip_command(command);
             PDB_delete_breakpoint(interpreter,command);
             break;
         case c_r:
         case c_run:
-            na(command);
+            command = skip_command(command);
             PDB_init(interpreter,command);
             PDB_continue(interpreter, NULL);
             break;
         case c_c:
         case c_continue:
-            na(command);
+            command = skip_command(command);
             PDB_continue(interpreter,command);
             break;
         case c_p:
         case c_print:
-            na(command);
+            command = skip_command(command);
             PDB_print(interpreter,command);
             break;
         case c_s:
         case c_stack:
-            na(command);
+            command = skip_command(command);
             PDB_print_stack(interpreter,command);
             break;
         case c_n:
         case c_next:
-            na(command);
+            command = skip_command(command);
             PDB_next(interpreter,command);
             break;
         case c_t:
         case c_trace:
-            na(command);
+            command = skip_command(command);
             PDB_trace(interpreter,command);
             break;
         case c_e:
         case c_eval:
-            na(command);
+            command = skip_command(command);
             PDB_eval(interpreter,command);
             break;
         case c_info:
-            na(command);
+            command = skip_command(command);
             PDB_info(interpreter);
             break;
         case c_h:
         case c_help:
-            na(command);
+            command = skip_command(command);
             PDB_help(command);
             break;
         case c_q:
@@ -185,11 +296,12 @@ PDB_run_command(struct Parrot_Interp *in
             pdb->state |= PDB_EXIT;
             break;
         case 0:
-            PDB_run_command(interpreter,pdb->last_command);
+            if (pdb->last_command)
+                PDB_run_command(interpreter,pdb->last_command);
             break;
         default:
             fprintf(stderr,"Undefined command: \"%s\".  Try \"help\".",
-                                                                 command);
+                    command);
             break;
     }
 }
@@ -211,7 +323,7 @@ PDB_next(struct Parrot_Interp *interpret
     /* Init the program if it's not running */
     if (!(pdb->state & PDB_RUNNING))
         PDB_init(interpreter,command);
-    
+
     /* Get the number of operations to execute if any */
     if (command && isdigit((int) *command))
         n = atol(command);
@@ -502,6 +614,7 @@ PDB_init(struct Parrot_Interp *interpret
     struct PackFile *code;
     unsigned long i;
     char c[256];
+    void* stacktop = interpreter->lo_var_ptr;
     
     /* The bytecode is readonly, right? */
     code = interpreter->code;
@@ -511,6 +624,7 @@ PDB_init(struct Parrot_Interp *interpret
     interpreter = make_interpreter(NO_FLAGS);
     interpreter->code = code;
     interpreter->pdb = pdb;
+    interpreter->lo_var_ptr = stacktop;
 
     /* set the user arguments */
     userargv = pmc_new(interpreter, enum_class_PerlArray);
@@ -525,8 +639,7 @@ PDB_init(struct Parrot_Interp *interpret
         c[i] = '\0';
         na(command);
 
-        arg = string_make(interpreter, c, i, NULL, 
-                          BUFFER_external_FLAG, NULL);
+        arg = string_make(interpreter, c, i, NULL, 0, NULL);
         userargv->vtable->push_string(interpreter, userargv, arg);
     }
 
@@ -1323,11 +1436,15 @@ PDB_eval(struct Parrot_Interp *interpret
     int op_number,i,k,l,j = 0;
 
     /* find_op needs a string with only the opcode name */
-    while (command && !(isspace((int) *command))) 
+    while (*command && !(isspace((int) *command))) 
         *(c++) = *(command++);
     *c = '\0';
     /* Find the opcode number */
     op_number = interpreter->op_lib->op_code(buf);
+    if (op_number < 0) {
+        fprintf(stderr, "Invalid opcode '%s'\n", buf);
+        return;
+    }
     /* Start generating the bytecode */
     eval[j++] = (opcode_t)op_number;
     /* Get the info for that opcode */
@@ -1335,7 +1452,7 @@ PDB_eval(struct Parrot_Interp *interpret
 
     /* handle the arguments */
     for (i = 1; i < op_info->arg_count; i++) {
-        na(command);
+        command = nextarg(command);
         switch (op_info->types[i]) { 
             /* If it's a register skip the letter that
                presides the register number */
@@ -1373,6 +1490,10 @@ PDB_eval(struct Parrot_Interp *interpret
                 /* Add it to the bytecode */
                 eval[j++] = (opcode_t)k;
                 break;
+            case PARROT_ARG_KIC:
+                command++; /* Skip opening [ */
+                eval[j++] = (opcode_t)atoi(command);
+                break;
             default:
                 break;
         }
@@ -1414,8 +1535,7 @@ PDB_print_stack(struct Parrot_Interp *in
     if (!*command || isdigit((int) *command))
         PDB_print_user_stack(interpreter,command);
     else {
-        for (i = 0; ((command[i] != 32) && command[i]) ; i++)
-            c += (command[i] + (i + 1)) * ((i + 1) * 255);
+        parse_command(command, &c);
 
         switch (c) {
             case c_i:
@@ -1465,7 +1585,7 @@ PDB_print_stack_int(struct Parrot_Interp
     fprintf(stderr,"Integer stack, frame %li, depth %li\n", i, depth);
 
     na(command);
-    PDB_print_int(&chunk->IReg[depth],command);
+    PDB_print_int(&chunk->IReg[depth], atoi(command));
 }
 
 /* PDB_print_stack_num
@@ -1488,7 +1608,7 @@ PDB_print_stack_num(struct Parrot_Interp
     fprintf(stderr,"Float stack, frame %li, depth %li\n", i, depth);
 
     na(command);
-    PDB_print_num(&chunk->NReg[depth],command);
+    PDB_print_num(&chunk->NReg[depth], atoi(command));
 }
 
 /* PDB_print_stack_string
@@ -1511,7 +1631,7 @@ PDB_print_stack_string(struct Parrot_Int
     fprintf(stderr,"String stack, frame %li, depth %li\n", i, depth);
 
     na(command);
-    PDB_print_string(interpreter,&chunk->SReg[depth],command);
+    PDB_print_string(interpreter,&chunk->SReg[depth], atoi(command));
 }
 
 /* PDB_print_stack_pmc
@@ -1534,9 +1654,24 @@ PDB_print_stack_pmc(struct Parrot_Interp
     fprintf(stderr,"PMC stack, frame %li, depth %li\n", i, depth);
 
     na(command);
-    PDB_print_pmc(interpreter,&chunk->PReg[depth],command);
+    PDB_print_pmc(interpreter,&chunk->PReg[depth], atoi(command), NULL);
 } 
 
+static void dump_string(struct Parrot_Interp *interpreter, STRING* s)
+{
+    if (s) {
+        fprintf(stderr,"\tBuflen  =\t%12ld\n",s->buflen);
+        fprintf(stderr,"\tFlags   =\t%12ld\n",s->flags);
+        fprintf(stderr,"\tBufused =\t%12ld\n",s->bufused);
+        fprintf(stderr,"\tBuflen  =\t%12ld\n",s->buflen);
+        fprintf(stderr,"\tStrlen  =\t%12ld\n",s->strlen);
+        fprintf(stderr,"\tOffset  =\t%12d\n",
+                (char*) s->strstart - (char*) s->bufstart);
+        fprintf(stderr,"\tString  =\t%s\n",
+                string_to_cstring(interpreter, s));
+    }
+}
+
 /* PDB_print_user_stack
  * print an entry from the user stack
  */
@@ -1560,14 +1695,8 @@ PDB_print_user_stack(struct Parrot_Inter
             fprintf(stderr,"Float\t=\t%8.4f\n",entry->entry.num_val);
             break;
         case STACK_ENTRY_STRING:
-            s = entry->entry.string_val;
             fprintf(stderr,"String =\n");
-            fprintf(stderr,"\tBuflen  =\t%8ld\n",s->buflen);
-            fprintf(stderr,"\tFlags   =\t%8ld\n",s->flags);
-            fprintf(stderr,"\tBufused =\t%8ld\n",s->bufused);
-            fprintf(stderr,"\tStrlen  =\t%8ld\n",s->strlen);
-            fprintf(stderr,"\tString  =\t%s\n",
-                string_to_cstring(interpreter, s));
+            dump_string(interpreter, entry->entry.string_val);
             break;
         case STACK_ENTRY_PMC:
             fprintf(stderr,"PMC =\n");
@@ -1588,7 +1717,11 @@ PDB_print_user_stack(struct Parrot_Inter
             break;
     }
 }
-  
+
+static STRING* cstring_to_string(struct Parrot_Interp *interpreter, char* str)
+{
+    return string_make(interpreter, str, strlen(str), NULL, 0, NULL);
+}
 
 /* PDB_print
  * print interpreter registers
@@ -1598,50 +1731,64 @@ PDB_print(struct Parrot_Interp *interpre
 {
     int i;
     unsigned long c = 0;
+    PMC* key = NULL;
+    int regnum = -1;
 
-    for (i = 0; ((command[i] != 32) && command[i]) ; i++)
-        c += (command[i] + (i + 1)) * ((i + 1) * 255);
+    command = skip_ws(command);
+    command = parse_command(command, &c);
+    command = skip_ws(command);
+
+    if (isdigit((int) *command)) {
+        command = parse_int(command, &regnum);
+        command = skip_ws(command);
+    }
+
+    interpreter->DOD_block_level++;
+
+    if (*command == '[') {
+        command = parse_key(interpreter, command, &key);
+    }
 
     switch (c) {
         case c_i:
         case c_int:
-            na(command);
-            PDB_print_int(&interpreter->ctx.int_reg,command);
+            PDB_print_int(&interpreter->ctx.int_reg, regnum);
             break;
         case c_n:
         case c_num:
-            na(command);
-            PDB_print_num(&interpreter->ctx.num_reg,command);
+            PDB_print_num(&interpreter->ctx.num_reg, regnum);
             break;
         case c_s:
         case c_str:
-            na(command);
-            PDB_print_string(interpreter,&interpreter->ctx.string_reg,command);
+            PDB_print_string(interpreter,&interpreter->ctx.string_reg, regnum);
             break;
         case c_p:
         case c_pmc:
-            na(command);
-            PDB_print_pmc(interpreter,&interpreter->ctx.pmc_reg,command);
+            PDB_print_pmc(interpreter,&interpreter->ctx.pmc_reg, regnum, key);
             break;
+        default:
+            fprintf(stderr, "Unrecognized print option: must be 'int', 'num', 'str', 
+'pmc', or a register\n");
     }
+
+    interpreter->DOD_block_level--;
 }
 
 /* PDB_print_int
  * print the whole or a specific value of a integer register structure.
  */
 void
-PDB_print_int(struct IReg *int_reg, const char *command)
+PDB_print_int(struct IReg *int_reg, int regnum)
 {
     int i,j = 0, k = NUM_REGISTERS;
 
-    if (command && *command) {
-        j = atoi(command);
-        k = j + 1;
+    if (regnum != -1) {
+        j = regnum;
+        k = regnum + 1;
     }
 
     fprintf(stderr,"Integer Registers:\n");
     for (i = j; i < k; i++) {
-        fprintf(stderr,"%2i =\t",i);
+        fprintf(stderr,"I%i =\t",i);
         fprintf(stderr,"%11li\n",int_reg->registers[i]);
     }
 }
@@ -1650,18 +1797,18 @@ PDB_print_int(struct IReg *int_reg, cons
  * print the whole or a specific value of a float register structure.
  */
 void
-PDB_print_num(struct NReg *num_reg, const char *command)
+PDB_print_num(struct NReg *num_reg, int regnum)
 {
     int i,j = 0, k = NUM_REGISTERS;
 
-    if (command && *command) {
-        j = atoi(command);
-        k = j + 1;
+    if (regnum != -1) {
+        j = regnum;
+        k = regnum + 1;
     }
 
     fprintf(stderr,"Float Registers:\n");
     for (i = j; i < k; i++) {
-        fprintf(stderr,"%2i =\t",i);
+        fprintf(stderr,"N%i =\t",i);
         fprintf(stderr,"%20.4f\n",num_reg->registers[i]);
     }
 }
@@ -1671,66 +1818,66 @@ PDB_print_num(struct NReg *num_reg, cons
  */
 void
 PDB_print_string(struct Parrot_Interp *interpreter, struct SReg *string_reg,
-                 const char *command)
+                 int regnum)
 {
     int i,j = 0, k = NUM_REGISTERS;
     STRING *s;
 
-    if (command && *command) {
-        j = atoi(command);
-        k = j + 1;
+    if (regnum != -1) {
+        j = regnum;
+        k = regnum + 1;
     }
-        
+
     fprintf(stderr,"String Registers:\n");
     for (i = j; i < k; i++) {
-        fprintf(stderr,"%2i =\n",i);
-        s = string_reg->registers[i];
+        fprintf(stderr,"S%i =\n",i);
+        dump_string(interpreter, string_reg->registers[i]);
+    }
+}
+
+static void
+print_pmc(struct Parrot_Interp *interpreter, PMC* pmc)
+{
+    if (pmc && pmc->vtable) {
+        STRING* s = pmc->vtable->name(interpreter, pmc);
         if (s) {
-            fprintf(stderr,"\tBuflen  =\t%12ld\n",s->buflen);
-            fprintf(stderr,"\tFlags   =\t%12ld\n",s->flags);
-            fprintf(stderr,"\tBufused =\t%12ld\n",s->bufused);
-            fprintf(stderr,"\tStrlen  =\t%12ld\n",s->strlen);
-            fprintf(stderr,"\tString  =\t%s\n",
-                string_to_cstring(interpreter, s));
+            fprintf(stderr, " [%s]\n", string_to_cstring(interpreter, s));
         }
+        s = (pmc->vtable->get_string(interpreter, pmc));
+        if (s) {
+            fprintf(stderr,"Stringified: %s\n",
+                    string_to_cstring(interpreter, s));
+        }
+    } 
+    else {
+        fprintf(stderr, "<null pmc>\n");
     }
 }
 
-/* PDB_print_pmc
- * print the whole or a specific value of a pmc register structure.
- */
 void
 PDB_print_pmc(struct Parrot_Interp *interpreter, struct PReg *pmc_reg,
-              const char *command)
+              int regnum, PMC* key)
 {
     int i,j = 0, k = NUM_REGISTERS;
     STRING *s;
 
-    if (command && *command) {
-        j = atoi(command);
-        k = j + 1;
+    if (regnum != -1) {
+        j = regnum;
+        k = regnum + 1;
     }
 
-    fprintf(stderr,"PMC Registers:\n");
+    if (regnum == -1)
+        fprintf(stderr,"PMC Registers:\n");
+
     for (i = j; i < k; i++) {
-        fprintf(stderr,"%2i =",i);
-        if (pmc_reg->registers[i] && pmc_reg->registers[i]->vtable) {
-            s = (pmc_reg->registers[i]->vtable->name(interpreter, 
-                                                     pmc_reg->registers[i]));
-            if (s) {
-                fprintf(stderr, " [%s]\n", 
-                        string_to_cstring(interpreter, (s)));
-            }
-            s = (pmc_reg->registers[i]->vtable->get_string(
-                 interpreter, pmc_reg->registers[i]));
+        PMC* pmc = pmc_reg->registers[i];
 
-            if (s) {
-                fprintf(stderr,"%s\n", string_to_cstring(interpreter, (s)));
-            }
-        } 
-        else {
-            fprintf(stderr, "\n");
-        }
+        fprintf(stderr,"P%i", i);
+        if (key) trace_key_dump(interpreter, key);
+        fprintf(stderr," =");
+
+        if (key) pmc = pmc->vtable->get_pmc_keyed(interpreter, pmc, key);
+        print_pmc(interpreter, pmc);
     }
 }
 
Index: embed.c
===================================================================
RCS file: /cvs/public/parrot/embed.c,v
retrieving revision 1.39
diff -p -u -r1.39 embed.c
--- embed.c     20 Aug 2002 00:30:36 -0000      1.39
+++ embed.c     26 Aug 2002 02:33:44 -0000
@@ -237,10 +237,38 @@ Parrot_loadbc(struct Parrot_Interp *inte
 }
 
 void
+Parrot_setup_argv(struct Parrot_Interp *interpreter, int argc, char ** argv)
+{
+    int i;
+    PMC *userargv;
+
+    if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
+        fprintf(stderr,
+                "*** Parrot VM: Setting up ARGV array in P0.  Current argc: %d ***\n",
+                argc);
+    }
+    
+    userargv = pmc_new(interpreter, enum_class_PerlArray);
+    /* immediately anchor pmc to root set */
+    interpreter->ctx.pmc_reg.registers[0] = userargv;
+
+    for (i = 0; i < argc; i++) {
+        /* Run through argv, adding everything to @ARGS. */
+        STRING *arg = string_make(interpreter, argv[i], strlen(argv[i]),
+                                  0, BUFFER_external_FLAG, 0);
+
+        if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
+            fprintf(stderr, "\t%d: %s\n", i, argv[i]);
+        }
+
+        userargv->vtable->push_string(interpreter, userargv, arg);
+    }
+}
+
+void
 Parrot_runcode(struct Parrot_Interp *interpreter, int argc, char *argv[])
 {
     INTVAL i;
-    PMC *userargv;
 
     /* Debugging mode nonsense. */
     if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
@@ -272,30 +300,10 @@ Parrot_runcode(struct Parrot_Interp *int
     
 #endif
 
-    if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
-        fprintf(stderr,
-                "*** Parrot VM: Setting up ARGV array in P0.  Current argc: %d ***\n",
-                argc);
-    }
-    
     /* Set up @ARGS (or whatever this language calls it).
        XXX Should this be Array or PerlArray?             */
-    
-    userargv = pmc_new(interpreter, enum_class_PerlArray);
-    /* immediately anchor pmc to root set */
-    interpreter->ctx.pmc_reg.registers[0] = userargv;
 
-    for (i = 0; i < argc; i++) {
-        /* Run through argv, adding everything to @ARGS. */
-        STRING *arg = string_make(interpreter, argv[i], strlen(argv[i]),
-                                  0, BUFFER_external_FLAG, 0);
-
-        if (Interp_flags_TEST(interpreter, PARROT_DEBUG_FLAG)) {
-            fprintf(stderr, "\t" INTVAL_FMT ": %s\n", i, argv[i]);
-        }
-
-        userargv->vtable->push_string(interpreter, userargv, arg);
-    }
+    Parrot_setup_argv(interpreter, argc, argv);
     
     /* Let's kick the tires and light the fires--call interpreter.c:runops. */
     runops(interpreter, interpreter->code, 0);
@@ -377,8 +385,32 @@ Parrot_destroy(struct Parrot_Interp *int
     free(interp);
 }
 
+/* XXX Doesn't handle arguments with spaces */
+static char*
+argv_join(char ** argv)
+{
+    char* command;
+    char* p;
+    int space = 0;
+    int i;
+
+    for (i = 0; argv[i]; i++)
+        space += strlen(argv[i]) + 1;
+
+    command = (char*) malloc(space == 0 ? 1 : space);
+    p = command;
+    for (i = 0; argv[i]; i++) {
+        strcpy(p, argv[i]);
+        p += strlen(argv[i]);
+        *(p++) = ' ';
+    }
+    if (p > command) p--;
+    *p = '\0';
+    return command;
+}
+
 void
-Parrot_debug(struct Parrot_Interp *interpreter)
+Parrot_debug(struct Parrot_Interp *interpreter, int argc, char ** argv)
 {
     PDB_t *pdb;
     const char *command;
@@ -388,7 +420,8 @@ Parrot_debug(struct Parrot_Interp *inter
     interpreter->pdb = pdb;
     pdb->cur_opcode = interpreter->code->byte_code;
 
-    PDB_init(interpreter,NULL);
+    /* Parrot_setup_argv(interpreter, argc, argv); */
+    PDB_init(interpreter, argv_join(argv));
     PDB_disassemble(interpreter,NULL);
     while (!(pdb->state & PDB_EXIT)) {
         PDB_get_command(interpreter);
Index: trace.c
===================================================================
RCS file: /cvs/public/parrot/trace.c,v
retrieving revision 1.20
diff -p -u -r1.20 trace.c
--- trace.c     21 Aug 2002 08:00:10 -0000      1.20
+++ trace.c     26 Aug 2002 02:33:45 -0000
@@ -15,10 +15,8 @@
 
 /*
  *=for api interpreter trace_key_dump
- * TODO: This isn't really part of the API, but here's its documentation. 
- * Prints a key. Used by trace_op_dump
+ * Prints a key to stderr.
  */
-static
 void
 trace_key_dump(struct Parrot_Interp *interpreter, PMC *key)
 {
Index: debug.ops
===================================================================
RCS file: /cvs/public/parrot/debug.ops,v
retrieving revision 1.2
diff -p -u -r1.2 debug.ops
--- debug.ops   4 Jul 2002 20:39:44 -0000       1.2
+++ debug.ops   26 Aug 2002 02:33:46 -0000
@@ -119,10 +119,10 @@ Print all the parrot registers at once.
 
 op debug_print() {
     if (!(interpreter->pdb->state & PDB_BREAK)) {
-        PDB_print_int(&interpreter->ctx.int_reg,NULL);
-        PDB_print_num(&interpreter->ctx.num_reg,NULL);
-        PDB_print_string(interpreter,&interpreter->ctx.string_reg,NULL);
-        PDB_print_pmc(interpreter,&interpreter->ctx.pmc_reg,NULL);
+        PDB_print_int(&interpreter->ctx.int_reg, -1);
+        PDB_print_num(&interpreter->ctx.num_reg, -1);
+        PDB_print_string(interpreter,&interpreter->ctx.string_reg, -1);
+        PDB_print_pmc(interpreter,&interpreter->ctx.pmc_reg, -1, NULL);
     }
     goto NEXT();
 }
Index: include/parrot/embed.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/embed.h,v
retrieving revision 1.14
diff -p -u -r1.14 embed.h
--- include/parrot/embed.h      17 Aug 2002 01:09:04 -0000      1.14
+++ include/parrot/embed.h      26 Aug 2002 02:33:46 -0000
@@ -34,11 +34,13 @@ Parrot_PackFile Parrot_readbc(Parrot_Int
 
 void Parrot_loadbc(Parrot_Interp, Parrot_PackFile);
 
+void Parrot_setup_argv(Parrot_Interp, int argc, char ** argv);
+
 void Parrot_runcode(Parrot_Interp, int argc, char *argv[]);
 
 void Parrot_destroy(Parrot_Interp);
 
-void Parrot_debug(Parrot_Interp);
+void Parrot_debug(Parrot_Interp, int argc, char ** argv);
 
 void Parrot_disassemble(Parrot_Interp);
 
Index: include/parrot/trace.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/trace.h,v
retrieving revision 1.9
diff -p -u -r1.9 trace.h
--- include/parrot/trace.h      9 Jun 2002 23:29:29 -0000       1.9
+++ include/parrot/trace.h      26 Aug 2002 02:33:46 -0000
@@ -15,6 +15,8 @@
 
 #include "parrot/parrot.h"
 
+void trace_key_dump(struct Parrot_Interp *interpreter, PMC *key);
+
 void trace_op_dump(struct Parrot_Interp *interpreter, opcode_t * code_start,
                    opcode_t * pc);
 
Index: include/parrot/debug.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/debug.h,v
retrieving revision 1.12
diff -p -u -r1.12 debug.h
--- include/parrot/debug.h      25 Aug 2002 23:38:44 -0000      1.12
+++ include/parrot/debug.h      26 Aug 2002 02:37:47 -0000
@@ -152,15 +152,15 @@ void PDB_get_command(struct Parrot_Inter
 
 void PDB_print(struct Parrot_Interp *, const char *);
 
-void PDB_print_int(struct IReg *, const char *);
+void PDB_print_int(struct IReg *, int);
 
-void PDB_print_num(struct NReg *, const char *);
+void PDB_print_num(struct NReg *, int);
 
 void PDB_print_string(struct Parrot_Interp *interpreter,
-                      struct SReg *, const char *);
+                      struct SReg *, int);
 
 void PDB_print_pmc(struct Parrot_Interp *interpreter,
-                   struct PReg *, const char *);
+                   struct PReg *, int, PMC* key);
 
 void PDB_debug(struct Parrot_Interp *);
 
Index: pdb.c
===================================================================
RCS file: /cvs/public/parrot/pdb.c,v
retrieving revision 1.3
diff -p -u -r1.3 pdb.c
--- pdb.c       17 Aug 2002 01:11:08 -0000      1.3
+++ pdb.c       26 Aug 2002 06:24:39 -0000
@@ -37,8 +37,8 @@ main(int argc, char *argv[])
 
     Parrot_init(interpreter, (void*) &interpreter);
 
-    if (argc != 2) {
-        fprintf(stderr, "Usage: pdb programfile\n");
+    if (argc < 2) {
+        fprintf(stderr, "Usage: pdb programfile [program-options]\n");
         exit(1);
     }
 
@@ -54,7 +54,7 @@ main(int argc, char *argv[])
 
     Parrot_loadbc(interpreter, pf);
     PDB_printwelcome();
-    Parrot_debug(interpreter);
+    Parrot_debug(interpreter, argc-1, argv+1);
     Parrot_destroy(interpreter);
 
     return 0;

Reply via email to