Author: julianalbo
Date: Thu Aug 21 04:54:52 2008
New Revision: 30423

Modified:
   trunk/src/debug.c

Log:
refactor debugger command dispatch

Modified: trunk/src/debug.c
==============================================================================
--- trunk/src/debug.c   (original)
+++ trunk/src/debug.c   Thu Aug 21 04:54:52 2008
@@ -176,6 +176,264 @@
 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END.  Your changes will 
be lost. */
 /* HEADERIZER END: static */
 
+/*
+ *  Command functions and help dispatch
+ */
+
+typedef void (* debugger_func_t)(PARROT_INTERP, ARGIN(const char * cmd));
+
+
+static void dbg_echo(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_echo");
+
+    if (interp->pdb->state & PDB_ECHO) {
+        TRACEDEB_MSG("Disabling echo");
+        interp->pdb->state &= ~PDB_ECHO;
+    }
+    else {
+        TRACEDEB_MSG("Enabling echo");
+        interp->pdb->state |= PDB_ECHO;
+    }
+}
+
+static void dbg_gcdebug(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_gcdebug");
+
+    if (interp->pdb->state & PDB_GCDEBUG) {
+        TRACEDEB_MSG("Disabling gcdebug mode");
+        interp->pdb->state &= ~PDB_GCDEBUG;
+    }
+    else {
+        TRACEDEB_MSG("Enabling gcdebug mode");
+        interp->pdb->state |= PDB_GCDEBUG;
+    }
+}
+
+static void dbg_info(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_info");
+
+    PDB_info(interp);
+}
+
+static void dbg_quit(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_quit");
+
+    interp->pdb->state |= PDB_EXIT;
+    interp->pdb->state &= ~PDB_STOPPED;
+}
+
+static void dbg_run(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER SKIP 
*/
+{
+    TRACEDEB_MSG("dbg_run");
+
+    PDB_init(interp, cmd);
+    PDB_continue(interp, NULL);
+}
+
+static void dbg_script(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_script");
+ 
+    PDB_script_file(interp, cmd);
+}
+
+static void dbg_stack(PARROT_INTERP, ARGIN(const char * cmd)) /* HEADERIZER 
SKIP */
+{
+    TRACEDEB_MSG("dbg_stack");
+ 
+    PDB_backtrace(interp);
+}
+
+typedef struct DebuggerCmd_t {
+    debugger_func_t func;
+    const char * const help;
+} DebuggerCmd;
+
+static const DebuggerCmd
+    cmd_break = {
+        & PDB_set_break,
+"Set a breakpoint at a given line number (which must be specified).\n\n\
+Optionally, specify a condition, in which case the breakpoint will only\n\
+activate if the condition is met. Conditions take the form:\n\n\
+           if [REGISTER] [COMPARISON] [REGISTER or CONSTANT]\n\n\
+\
+For example:\n\n\
+           break 10 if I4 > I3\n\n\
+           break 45 if S1 == \"foo\"\n\n\
+The command returns a number which is the breakpoint identifier."
+    },
+    cmd_continue = {
+        & PDB_continue,
+"Continue the program execution.\n\n\
+Without arguments, the program runs until a breakpoint is found\n\
+(or until the program terminates for some other reason).\n\n\
+If a number is specified, then skip that many breakpoints.\n\n\
+If the program has terminated, then \"continue\" will do nothing;\n\
+use \"run\" to re-run the program."
+    },
+    cmd_delete = {
+        & PDB_delete_breakpoint,
+"Delete a breakpoint.\n\n\
+The breakpoint to delete must be specified by its breakpoint number.\n\
+Deleted breakpoints are gone completely. If instead you want to\n\
+temporarily disable a breakpoint, use \"disable\"."
+    },
+    cmd_disable = {
+        & PDB_disable_breakpoint,
+"Disable a breakpoint.\n\n\
+The breakpoint to disable must be specified by its breakpoint number.\n\
+Disabled breakpoints are not forgotten, but have no effect until re-enabled\n\
+with the \"enable\" command."
+    },
+    cmd_disassemble = {
+        & PDB_disassemble,
+"Disassemble code"
+    },
+    cmd_echo = {
+        & dbg_echo,
+"Toggle echo mode.\n\n\
+In echo mode the script commands are written to stderr before executing."
+    },
+    cmd_enable = {
+        & PDB_enable_breakpoint,
+"Re-enable a disabled breakpoint."
+    },
+    cmd_eval = {
+        & PDB_eval,
+"No documentation yet"
+    },
+    cmd_gcdebug = {
+        & dbg_gcdebug,
+"Toggle gcdebug mode.\n\n\
+In gcdebug mode a garbage collection cycle is run before each opcocde,\n\
+same as using the gcdebug core."
+    },
+    cmd_help = {
+        & PDB_help,
+"Print a list of available commands."
+    },
+    cmd_info = {
+        & dbg_info,
+"Print information about the current interpreter"
+    },
+    cmd_list = {
+        & PDB_list,
+"List the source code.\n\n\
+Optionally specify the line number to begin the listing from and the number\n\
+of lines to display."
+    },
+    cmd_load = {
+        & PDB_load_source,
+"Load a source code file."
+    },
+    cmd_next = {
+        & PDB_next,
+"Execute a specified number of instructions.\n\n\
+If a number is specified with the command (e.g. \"next 5\"), then\n\
+execute that number of instructions, unless the program reaches a\n\
+breakpoint, or stops for some other reason.\n\n\
+If no number is specified, it defaults to 1."  
+    },
+    cmd_print = {
+        & PDB_print,
+"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."
+    },
+    cmd_quit = {
+        & dbg_quit,
+"Exit the debugger"
+    },
+    cmd_run = {
+        & dbg_run,
+"Run (or restart) the program being debugged.\n\n\
+Arguments specified after \"run\" are passed as command line arguments to\n\
+the program.\n"
+    },
+    cmd_script = {
+        & dbg_script,
+"Interprets a file s user commands.\n\
+Usage:\n\
+(pdb) script file.script"
+    },
+    cmd_stack = {
+        & dbg_stack,
+"Print a stack trace of the parrot VM"
+    },
+    cmd_trace = {
+        & PDB_trace,
+"Similar to \"next\", but prints additional trace information.\n\
+This is the same as the information you get when running Parrot with\n\
+the -t option.\n"
+    },
+    cmd_watch = {
+        & PDB_watchpoint,
+"Add a watchpoint"
+    };
+
+static const DebuggerCmd * get_command(long cmdhash) /* HEADERIZER SKIP */
+{
+    switch ((enum DebugCmd)cmdhash) {
+        case debug_cmd_break:
+            return & cmd_break;
+        case debug_cmd_continue:
+        case debug_cmd_c:
+            return & cmd_continue;
+        case debug_cmd_delete:
+        case debug_cmd_d:
+            return & cmd_delete;
+        case debug_cmd_disable:
+            return & cmd_disable;
+        case debug_cmd_disassemble:
+            return & cmd_disassemble;
+        case debug_cmd_echo:
+            return & cmd_echo;
+        case debug_cmd_enable:
+            return & cmd_enable;
+        case debug_cmd_eval:
+        case debug_cmd_e:
+            return & cmd_eval;
+        case debug_cmd_gcdebug:
+            return & cmd_gcdebug;
+        case debug_cmd_help:
+        case debug_cmd_h:
+            return & cmd_help;
+        case debug_cmd_info:
+            return & cmd_info;
+        case debug_cmd_list:
+        case debug_cmd_l:
+            return & cmd_list;
+        case debug_cmd_load:
+            return & cmd_load;
+        case debug_cmd_next:
+        case debug_cmd_n:
+            return & cmd_next;
+        case debug_cmd_print:
+        case debug_cmd_p:
+             return & cmd_print;
+        case debug_cmd_quit:
+        case debug_cmd_q:
+             return & cmd_quit;
+        case debug_cmd_r:
+        case debug_cmd_run:
+             return & cmd_run;
+        case debug_cmd_script_file:
+        case debug_cmd_f:
+            return & cmd_script;
+        case debug_cmd_stack:
+        case debug_cmd_s:
+            return & cmd_stack;
+        case debug_cmd_trace:
+        case debug_cmd_t:
+            return & cmd_trace;
+        default:
+            return NULL;
+    }
+}
 
 /*
 
@@ -816,6 +1074,7 @@
     unsigned long c;
     PDB_t        * const pdb = interp->pdb;
     const char   * const original_command = command;
+    const DebuggerCmd *cmd;
 
     TRACEDEB_MSG("PDB_run_command");
 
@@ -825,120 +1084,32 @@
     command = parse_command(original_command, &c);
 
     if (command)
-        skip_command(command);
+        command = skip_command(command);
     else
         return 0;
 
-    switch ((enum DebugCmd)c) {
-        case debug_cmd_f:
-        case debug_cmd_script_file:
-            command = nextarg(command);
-            PDB_script_file(interp, command);
-            break;
-        case debug_cmd_disassemble:
-            PDB_disassemble(interp, command);
-            break;
-        case debug_cmd_load:
-            PDB_load_source(interp, command);
-            break;
-        case debug_cmd_l:
-        case debug_cmd_list:
-            PDB_list(interp, command);
-            break;
-        case debug_cmd_b:
-        case debug_cmd_break:
-            PDB_set_break(interp, command);
-            break;
-        case debug_cmd_w:
-        case debug_cmd_watch:
-            PDB_watchpoint(interp, command);
-            break;
-        case debug_cmd_d:
-        case debug_cmd_delete:
-            PDB_delete_breakpoint(interp, command);
-            break;
-        case debug_cmd_disable:
-            PDB_disable_breakpoint(interp, command);
-            break;
-        case debug_cmd_enable:
-            PDB_enable_breakpoint(interp, command);
-            break;
-        case debug_cmd_r:
-        case debug_cmd_run:
-            PDB_init(interp, command);
-            PDB_continue(interp, NULL);
-            break;
-        case debug_cmd_c:
-        case debug_cmd_continue:
-            PDB_continue(interp, command);
-            break;
-        case debug_cmd_p:
-        case debug_cmd_print:
-            PDB_print(interp, command);
-            break;
-        case debug_cmd_n:
-        case debug_cmd_next:
-            PDB_next(interp, command);
-            break;
-        case debug_cmd_t:
-        case debug_cmd_trace:
-            PDB_trace(interp, command);
-            break;
-        case debug_cmd_e:
-        case debug_cmd_eval:
-            PDB_eval(interp, command);
-            break;
-        case debug_cmd_info:
-            PDB_info(interp);
-            break;
-        case debug_cmd_gcdebug:
-            if (pdb->state & PDB_GCDEBUG) {
-                TRACEDEB_MSG("Disabling gcdebug mode");
-                pdb->state &= ~PDB_GCDEBUG;
-            }
-            else {
-                TRACEDEB_MSG("Enabling gcdebug mode");
-                pdb->state |= PDB_GCDEBUG;
-            }
-            break;
-        case debug_cmd_echo:
-            if (pdb->state & PDB_ECHO) {
-                TRACEDEB_MSG("Disabling echo");
-                pdb->state &= ~PDB_ECHO;
-            }
-            else {
-                TRACEDEB_MSG("Enabling echo");
-                pdb->state |= PDB_ECHO;
-            }
-            break;
-        case debug_cmd_h:
-        case debug_cmd_help:
-            PDB_help(interp, command);
-            break;
-        case debug_cmd_q:
-        case debug_cmd_quit:
-            pdb->state |= PDB_EXIT;
-            pdb->state &= ~PDB_STOPPED;
-            break;
-        case debug_cmd_s:
-        case debug_cmd_stack:
-            PDB_backtrace(interp);
-            break;
-        case (enum DebugCmd)0:
+    cmd= get_command(c);
+    if (cmd) {
+        (* cmd->func)(interp, command);
+        return 0;
+    }
+    else {
+        if (c == 0) {
             /*
             if (pdb->last_command)
                 PDB_run_command(interp, pdb->last_command);
             */
-            break;
-        default:
+            return 0;
+        }
+        else {
             PIO_eprintf(interp,
                         "Undefined command: \"%s\".  Try \"help\".", 
original_command);
 #if TRACE_DEBUGGER
             fprintf(stderr, " (parse_command result: %li)", c);
 #endif
             return 1;
+        }
     }
-    return 0;
 }
 
 /*
@@ -966,7 +1137,8 @@
     if (!(pdb->state & PDB_RUNNING))
         PDB_init(interp, command);
 
-    command = nextarg(command);
+    /*command = nextarg(command);*/
+
     /* Get the number of operations to execute if any */
     if (command && isdigit((unsigned char) *command))
         n = atol(command);
@@ -1032,7 +1204,8 @@
         PDB_init(interp, command);
     */
 
-    command = nextarg(command);
+    /*command = nextarg(command);*/
+
     /* if the number of ops to run is specified, convert to a long */
     if (command && isdigit((unsigned char) *command))
         n = atol(command);
@@ -2616,7 +2789,8 @@
         return;
     }
 
-    command = nextarg(command);
+    /*command = nextarg(command);*/
+
     /* set the list line if provided */
     if (isdigit((unsigned char) *command)) {
         line_number = atol(command) - 1;
@@ -2828,121 +3002,19 @@
 PDB_help(PARROT_INTERP, ARGIN(const char *command))
 {
     unsigned long c;
+    const DebuggerCmd *cmd;
 
     /* Extract the command after leading whitespace (for error messages). */
     while (*command && isspace((unsigned char)*command))
         command++;
     parse_command(command, &c);
 
-    switch (c) {
-        case debug_cmd_disassemble:
-            PIO_eprintf(interp, "No documentation yet");
-            break;
-        case debug_cmd_load:
-            PIO_eprintf(interp, "No documentation yet");
-            break;
-        case debug_cmd_list:
-            PIO_eprintf(interp,
-            "List the source code.\n\n\
-Optionally specify the line number to begin the listing from and the number\n\
-of lines to display.\n");
-            break;
-        case debug_cmd_run:
-            PIO_eprintf(interp,
-            "Run (or restart) the program being debugged.\n\n\
-Arguments specified after \"run\" are passed as command line arguments to\n\
-the program.\n");
-            break;
-        case debug_cmd_break:
-            PIO_eprintf(interp,
-"Set a breakpoint at a given line number (which must be specified).\n\n\
-Optionally, specify a condition, in which case the breakpoint will only\n\
-activate if the condition is met. Conditions take the form:\n\n\
-           if [REGISTER] [COMPARISON] [REGISTER or CONSTANT]\n\n\
-\
-For example:\n\n\
-           break 10 if I4 > I3\n\n\
-           break 45 if S1 == \"foo\"\n\n\
-The command returns a number which is the breakpoint identifier.");
-            break;
-        case debug_cmd_script_file:
-PIO_eprintf(interp, "Interprets a file.\n\
-Usage:\n\
-(pdb) script file.script\n");
-            break;
-        case debug_cmd_watch:
-            PIO_eprintf(interp, "No documentation yet");
-            break;
-        case debug_cmd_delete:
-            PIO_eprintf(interp,
-"Delete a breakpoint.\n\n\
-The breakpoint to delete must be specified by its breakpoint number.\n\
-Deleted breakpoints are gone completely. If instead you want to\n\
-temporarily disable a breakpoint, use \"disable\".\n");
-            break;
-        case debug_cmd_disable:
-            PIO_eprintf(interp,
-"Disable a breakpoint.\n\n\
-The breakpoint to disable must be specified by its breakpoint number.\n\
-Disabled breakpoints are not forgotten, but have no effect until re-enabled\n\
-with the \"enable\" command.\n");
-            break;
-        case debug_cmd_enable:
-            PIO_eprintf(interp, "Re-enable a disabled breakpoint.\n");
-            break;
-        case debug_cmd_continue:
-            PIO_eprintf(interp,
-"Continue the program execution.\n\n\
-Without arguments, the program runs until a breakpoint is found\n\
-(or until the program terminates for some other reason).\n\n\
-If a number is specified, then skip that many breakpoints.\n\n\
-If the program has terminated, then \"continue\" will do nothing;\n\
-use \"run\" to re-run the program.\n");
-            break;
-        case debug_cmd_next:
-            PIO_eprintf(interp,
-"Execute a specified number of instructions.\n\n\
-If a number is specified with the command (e.g. \"next 5\"), then\n\
-execute that number of instructions, unless the program reaches a\n\
-breakpoint, or stops for some other reason.\n\n\
-If no number is specified, it defaults to 1.\n");
-            break;
-        case debug_cmd_eval:
-            PIO_eprintf(interp, "No documentation yet");
-            break;
-        case debug_cmd_trace:
-            PIO_eprintf(interp,
-"Similar to \"next\", but prints additional trace information.\n\
-This is the same as the information you get when running Parrot with\n\
-the -t option.\n");
-            break;
-        case debug_cmd_print:
-            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 debug_cmd_info:
-            PIO_eprintf(interp,
-                    "Print information about the current interpreter\n");
-            break;
-        case debug_cmd_gcdebug:
-            PIO_eprintf(interp,
-"Toggle gcdebug mode.\n\n\
-In gcdebug mode a garbage collection cycle is run before each opcocde,\n\
-same as using the gcdebug core.\n");
-            break;
-        case debug_cmd_echo:
-            PIO_eprintf(interp,
-"Toggle echo mode.\n\n\
-In echo mode the script commands are written to stderr before executing.\n");
-            break;
-        case debug_cmd_quit:
-            PIO_eprintf(interp, "Exit the debugger.\n");
-            break;
-        case debug_cmd_help:
-            PIO_eprintf(interp, "Print a list of available commands.\n");
-            break;
-        case 0:
+    cmd = get_command(c);
+    if (cmd) {
+        PIO_eprintf(interp, "%s\n", cmd->help);
+    }
+    else {
+        if (c == 0) {
             /* C89: strings need to be 509 chars or less */
             PIO_eprintf(interp, "\
 List of commands:\n\
@@ -2969,10 +3041,10 @@
     quit     (q) -- exit the debugger\n\
     help     (h) -- print this help\n\n\
 Type \"help\" followed by a command name for full documentation.\n\n");
-            break;
-        default:
-            PIO_eprintf(interp, "Unknown command: \"%s\".", command);
-            break;
+        }
+        else {
+            PIO_eprintf(interp, "Unknown command\n");
+        }
     }
 }
 

Reply via email to