# 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, ®num); + 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;