]> granicus.if.org Git - php/commitdiff
work on parameters to commands
authorkrakjoe <joe.watkins@live.co.uk>
Wed, 19 Feb 2014 00:33:49 +0000 (00:33 +0000)
committerkrakjoe <joe.watkins@live.co.uk>
Wed, 19 Feb 2014 00:33:49 +0000 (00:33 +0000)
phpdbg_break.c
phpdbg_cmd.c
phpdbg_cmd.h
phpdbg_list.c
phpdbg_print.c
phpdbg_prompt.c
phpdbg_set.c

index 67267550c542fe3b2c708d35a50c2f1b75d50faa..870f68a481c0910f0700414d1cd3359bdb593a82 100644 (file)
@@ -31,15 +31,15 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
  * Commands
  */
 const phpdbg_command_t phpdbg_break_commands[] = {
-       PHPDBG_COMMAND_D_EX(file,        "specify breakpoint by file:line",                        'F', break_file,    NULL, 1),
-       PHPDBG_COMMAND_D_EX(func,        "specify breakpoint by global function name",             'f', break_func,    NULL, 1),
-       PHPDBG_COMMAND_D_EX(method,      "specify breakpoint by class::method",                    'm', break_method,  NULL, 1),
-       PHPDBG_COMMAND_D_EX(address,     "specify breakpoint by address",                          'a', break_address, NULL, 1),
-       PHPDBG_COMMAND_D_EX(op,          "specify breakpoint by opcode",                           'O', break_op,      NULL, 1),
-       PHPDBG_COMMAND_D_EX(on,          "specify breakpoint by condition",                        'o', break_on,      NULL, 1),
-       PHPDBG_COMMAND_D_EX(at,          "specify breakpoint by location and condition",           'A', break_at,      NULL, 1),
-       PHPDBG_COMMAND_D_EX(lineno,      "specify breakpoint by line of currently executing file", 'l', break_lineno,  NULL, 1),
-       PHPDBG_COMMAND_D_EX(del,         "delete breakpoint by identifier number",                 'd', break_del,     NULL, 1),
+       PHPDBG_COMMAND_D_EX(file,        "specify breakpoint by file:line",                        'F', break_file,    NULL, "f"),
+       PHPDBG_COMMAND_D_EX(func,        "specify breakpoint by global function name",             'f', break_func,    NULL, "s"),
+       PHPDBG_COMMAND_D_EX(method,      "specify breakpoint by class::method",                    'm', break_method,  NULL, "m"),
+       PHPDBG_COMMAND_D_EX(address,     "specify breakpoint by address",                          'a', break_address, NULL, "a"),
+       PHPDBG_COMMAND_D_EX(op,          "specify breakpoint by opcode",                           'O', break_op,      NULL, "s"),
+       PHPDBG_COMMAND_D_EX(on,          "specify breakpoint by condition",                        'o', break_on,      NULL, "c"),
+       PHPDBG_COMMAND_D_EX(at,          "specify breakpoint by location and condition",           'A', break_at,      NULL, "*c"),
+       PHPDBG_COMMAND_D_EX(lineno,      "specify breakpoint by line of currently executing file", 'l', break_lineno,  NULL, "l"),
+       PHPDBG_COMMAND_D_EX(del,         "delete breakpoint by identifier number",                 'd', break_del,     NULL, "l"),
        PHPDBG_END_COMMAND
 };
 
index 27b8e15de896bc8123cb599bd7e93dced712a1ee..c0149b3ad2361164cac27d33fc9aabfe0764cad4 100644 (file)
@@ -471,11 +471,132 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param)
        stack->len++;
 } /* }}} */
 
+PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param_t **stack, char **why TSRMLS_DC) {
+       if (command && command->args) {
+               const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL;
+               const char *arg = command->args;
+               size_t expected = strlen(command->args),
+                          received = 0L;
+               zend_bool optional = 0;
+               
+               if (*arg == '|') {
+                       expected--;
+                       optional = 1;
+                       arg++;
+               }
+               
+               if (arg && !top && !optional) {
+                       asprintf(why,
+                               "%s expected arguments and received none", command->name);
+                       return FAILURE;
+               }
+
+               while (top && arg) {
+
+                       switch (*arg) {
+                               case '|': { 
+                                       expected--;
+                                       optional = 1;
+                                       arg++;
+                               } continue;
+                               
+                               case 'i': if (top->type != STR_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected raw input and got %s at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 's': if (top->type != STR_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected string and got %s at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+
+                               case 'n': if (top->type != NUMERIC_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected number and got %s at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 'm': if (top->type != METHOD_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected method and got %s  at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 'a': if (top->type != ADDR_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected address and got %s  at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 'f': if (top->type != FILE_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected file:line and got %s  at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 'c': if (top->type != COND_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected condition and got %s  at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case 'b': if (top->type != NUMERIC_PARAM) {
+                                       asprintf(why, 
+                                               "%s expected boolean and got %s  at parameter %d", 
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } else if (top->num > 1 || top->num < 0) {
+                                       asprintf(why, 
+                                               "%s expected boolean and got number at parameter %d",
+                                               command->name, phpdbg_get_param_type(top TSRMLS_CC),
+                                               (command->args - arg) + 1);
+                                       return FAILURE;
+                               } break;
+                               
+                               case '*': { /* do nothing */ } break;
+                       }
+                       top = top->next;
+                       received++;
+                       arg++;
+               }
+
+               if ((received < expected) && (arg && *arg) && !optional) {
+                       asprintf(why,
+                               "%s expected %d arguments (%s) and received %d",
+                               command->name,
+                               expected,
+                               command->args, 
+                               received);
+                       return FAILURE;
+               }
+       }
+       
+       return SUCCESS;
+}
+
 /* {{{ */
-PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) {
+PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) {
        const phpdbg_command_t *command = commands;
        phpdbg_param_t *name = *top;
        phpdbg_command_t *matched[3] = {NULL, NULL, NULL};
+       
        ulong matches = 0L;
        
        while (command && command->name && command->handler) {
@@ -491,23 +612,18 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman
        }
        
        switch (matches) {
-               case 0: 
+               case 0: if (!parent) {
                        asprintf(
                                why,
                                "The command %s could not be found", 
                                name->str);
-               } break;
+                        return NULL;
+               } else return parent;
                
                case 1: {
                        (*top) = (*top)->next;
-                       if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) {
-                               command = phpdbg_stack_resolve(matched[0]->subs, top, why);
-                               if (command) {
-                                       return command;
-                               }
-                       }
-                       
-                       return matched[0];
+
+                       command = matched[0];
                } break;
                
                default: {
@@ -515,9 +631,15 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman
                                why,
                                "The command %s is ambigious, matching %d commands", 
                                name->str, matches);
-               }
+               } return NULL;
        }
-       
+
+       if (command->subs && (*top) && ((*top)->type == STR_PARAM)) {
+               return phpdbg_stack_resolve(command->subs, command, top, why);
+       } else {
+               return command;
+       }
+
        return NULL;
 } /* }}} */
 
@@ -550,14 +672,14 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) {
                
                case STR_PARAM: {
                        handler = phpdbg_stack_resolve(
-                               phpdbg_prompt_commands, &command, why);
+                               phpdbg_prompt_commands, NULL, &command, why);
                        
                        if (handler) {
-                               return handler->handler(command, NULL TSRMLS_CC);
-                       } else {
-                               return FAILURE;
+                               if (phpdbg_stack_verify(handler, &command, why) == SUCCESS) {
+                                       return handler->handler(command, NULL TSRMLS_CC);
+                               }
                        }
-               } break;
+               } return FAILURE;
                
                default:
                        asprintf(
index d22650c67160b2e34040a993f40f2ecc48f7b4e4..23766c62da4a91cb2faf5b4a8f87ce807188c20a 100644 (file)
@@ -105,7 +105,7 @@ struct _phpdbg_command_t {
        char alias;                         /* Alias */
        phpdbg_command_handler_t handler;   /* Command handler */
        const phpdbg_command_t *subs;       /* Sub Commands */
-       char arg_type;                      /* Accept args? */
+       char *args;                                                     /* Argument Spec */                                                     
 };
 /* }}} */
 
@@ -147,7 +147,7 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC);
  * Stack Management
  */
 PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param);
-PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why);
+PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why);
 PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why);
 PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack);
 
@@ -168,17 +168,17 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
  */
 #define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name
 
-#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, has_args) \
-       {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, has_args}
+#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \
+       {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args}
 
-#define PHPDBG_COMMAND_D(name, tip, alias, children, has_args) \
-       {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, has_args}
+#define PHPDBG_COMMAND_D(name, tip, alias, children, args) \
+       {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args}
 
 #define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC)
 
 #define PHPDBG_COMMAND_ARGS param, input TSRMLS_CC
 
-#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'}
+#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', '\0'}
 
 /*
 * Default Switch Case
index 7177def8d62f0d2a1e2b50ed991ee786de28973e..a1bd8c0ff5310628c031b0f7de18be792cf567e4 100644 (file)
 ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
 
 const phpdbg_command_t phpdbg_list_commands[] = {
-       PHPDBG_COMMAND_D_EX(lines,     "lists the specified lines",    'l', list_lines,  NULL, 1),
-       PHPDBG_COMMAND_D_EX(class,     "lists the specified class",    'c', list_class,  NULL, 1),
-       PHPDBG_COMMAND_D_EX(method,    "lists the specified method",   'm', list_method, NULL, 1),
-       PHPDBG_COMMAND_D_EX(func,      "lists the specified function", 'f', list_func,   NULL, 1),
+       PHPDBG_COMMAND_D_EX(lines,     "lists the specified lines",    'l', list_lines,  NULL, "l"),
+       PHPDBG_COMMAND_D_EX(class,     "lists the specified class",    'c', list_class,  NULL, "s"),
+       PHPDBG_COMMAND_D_EX(method,    "lists the specified method",   'm', list_method, NULL, "m"),
+       PHPDBG_COMMAND_D_EX(func,      "lists the specified function", 'f', list_func,   NULL, "s"),
        PHPDBG_END_COMMAND
 };
 
index 7e549a277932e6bbee3e7014d8e5daa7d563c7fd..ed630c200c7f56fd905466dded8b76e0d2045a43 100644 (file)
@@ -29,9 +29,9 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
 const phpdbg_command_t phpdbg_print_commands[] = {
        PHPDBG_COMMAND_D_EX(exec,       "print out the instructions in the execution context",  'e', print_exec,   NULL, 0),
        PHPDBG_COMMAND_D_EX(opline,     "print out the instruction in the current opline",      'o', print_opline, NULL, 0),
-       PHPDBG_COMMAND_D_EX(class,      "print out the instructions in the specified class",    'c', print_class,  NULL, 1),
-       PHPDBG_COMMAND_D_EX(method,     "print out the instructions in the specified method",   'm', print_method, NULL, 1),
-       PHPDBG_COMMAND_D_EX(func,       "print out the instructions in the specified function", 'f', print_func,   NULL, 1),
+       PHPDBG_COMMAND_D_EX(class,      "print out the instructions in the specified class",    'c', print_class,  NULL, "s"),
+       PHPDBG_COMMAND_D_EX(method,     "print out the instructions in the specified method",   'm', print_method, NULL, "m"),
+       PHPDBG_COMMAND_D_EX(func,       "print out the instructions in the specified function", 'f', print_func,   NULL, "s"),
        PHPDBG_COMMAND_D_EX(stack,      "print out the instructions in the current stack",      's', print_stack,  NULL, 0),
        PHPDBG_END_COMMAND
 };
index 6aff5dd0d1a8f29329fd6f487dcaa310d383b148..1e1f048ebf8a3b2acac31bc1427db9a5d6b13896 100644 (file)
@@ -44,29 +44,29 @@ int yyparse(phpdbg_param_t *stack, yyscan_t scanner);
 
 /* {{{ command declarations */
 const phpdbg_command_t phpdbg_prompt_commands[] = {
-       PHPDBG_COMMAND_D(exec,    "set execution context",                    'e', NULL, 1),
+       PHPDBG_COMMAND_D(exec,    "set execution context",                    'e', NULL, "s"),
        PHPDBG_COMMAND_D(compile, "attempt compilation",                      'c', NULL, 0),
-       PHPDBG_COMMAND_D(step,    "step through execution",                   's', NULL, 1),
+       PHPDBG_COMMAND_D(step,    "step through execution",                   's', NULL, "b"),
        PHPDBG_COMMAND_D(next,    "continue execution",                       'n', NULL, 0),
        PHPDBG_COMMAND_D(run,     "attempt execution",                        'r', NULL, 0),
-       PHPDBG_COMMAND_D(eval,    "evaluate some code",                       'E', NULL, 1),
+       PHPDBG_COMMAND_D(eval,    "evaluate some code",                       'E', NULL, "i"),
        PHPDBG_COMMAND_D(until,   "continue past the current line",           'u', NULL, 0),
        PHPDBG_COMMAND_D(finish,  "continue past the end of the stack",       'F', NULL, 0),
        PHPDBG_COMMAND_D(leave,   "continue until the end of the stack",      'L', NULL, 0),
-       PHPDBG_COMMAND_D(print,   "print something",                          'p', phpdbg_print_commands, 2),
-       PHPDBG_COMMAND_D(break,   "set breakpoint",                           'b', phpdbg_break_commands, 1),
+       PHPDBG_COMMAND_D(print,   "print something",                          'p', phpdbg_print_commands, "s"),
+       PHPDBG_COMMAND_D(break,   "set breakpoint",                           'b', phpdbg_break_commands, 0),
        PHPDBG_COMMAND_D(back,    "show trace",                               't', NULL, 0),
-       PHPDBG_COMMAND_D(frame,   "switch to a frame",                        'f', NULL, 1),
-       PHPDBG_COMMAND_D(list,    "lists some code",                          'l', phpdbg_list_commands, 2),
-       PHPDBG_COMMAND_D(info,    "displays some informations",               'i', phpdbg_info_commands, 1),
+       PHPDBG_COMMAND_D(frame,   "switch to a frame",                        'f', NULL, "n"),
+       PHPDBG_COMMAND_D(list,    "lists some code",                          'l', phpdbg_list_commands, "*"),
+       PHPDBG_COMMAND_D(info,    "displays some informations",               'i', phpdbg_info_commands, "s"),
        PHPDBG_COMMAND_D(clean,   "clean the execution environment",          'X', NULL, 0),
        PHPDBG_COMMAND_D(clear,   "clear breakpoints",                        'C', NULL, 0),
-       PHPDBG_COMMAND_D(help,    "show help menu",                           'h', phpdbg_help_commands, 2),
-       PHPDBG_COMMAND_D(quiet,   "silence some output",                      'Q', NULL, 1),
-       PHPDBG_COMMAND_D(set,     "set phpdbg configuration",                 'S', phpdbg_set_commands,   1),
-       PHPDBG_COMMAND_D(register,"register a function",                      'R', NULL, 1),
-       PHPDBG_COMMAND_D(source,  "execute a phpdbginit",                     '.', NULL, 1),
-       PHPDBG_COMMAND_D(shell,   "shell a command",                          '-', NULL, 1),
+       PHPDBG_COMMAND_D(help,    "show help menu",                           'h', phpdbg_help_commands, "|s"),
+       PHPDBG_COMMAND_D(quiet,   "silence some output",                      'Q', NULL, "b"),
+       PHPDBG_COMMAND_D(set,     "set phpdbg configuration",                 'S', phpdbg_set_commands,   "s"),
+       PHPDBG_COMMAND_D(register,"register a function",                      'R', NULL, "s"),
+       PHPDBG_COMMAND_D(source,  "execute a phpdbginit",                     '.', NULL, "s"),
+       PHPDBG_COMMAND_D(shell,   "shell a command",                          '-', NULL, 0),
        PHPDBG_COMMAND_D(quit,    "exit phpdbg",                              'q', NULL, 0),
        PHPDBG_END_COMMAND
 }; /* }}} */
@@ -989,8 +989,10 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */
                                                        }*/
                                                        phpdbg_error("%s", why);
                                                }
-                                               if (why)
+                                               if (why) {
                                                        free(why);
+                                                       why = NULL;
+                                               }
                                        break;
 
                                        case PHPDBG_LEAVE:
@@ -1005,6 +1007,11 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */
                                }
                        }
                        
+                       if (why) {
+                               free(why);
+                               why = NULL;
+                       }
+                       
                        yy_delete_buffer(state, scanner);
                        yylex_destroy(scanner);
        
index 6280086da49cad1868bde1fdbbee7baa44c85d3b..a0dac2ea5bbed90ce4dfdb79b878254294e07386 100644 (file)
 ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
 
 const phpdbg_command_t phpdbg_set_commands[] = {
-       PHPDBG_COMMAND_D_EX(prompt,       "usage: set prompt <string>",          'p', set_prompt,       NULL, 0),
+       PHPDBG_COMMAND_D_EX(prompt,       "usage: set prompt <string>",          'p', set_prompt,       NULL, "s"),
 #ifndef _WIN32
-       PHPDBG_COMMAND_D_EX(color,        "usage: set color  <element> <color>", 'c', set_color,        NULL, 1),
-       PHPDBG_COMMAND_D_EX(colors,       "usage: set colors <on|off>",                  'C', set_colors,       NULL, 1),
+       PHPDBG_COMMAND_D_EX(color,        "usage: set color  <element> <color>", 'c', set_color,        NULL, "ss"),
+       PHPDBG_COMMAND_D_EX(colors,       "usage: set colors <on|off>",                  'C', set_colors,       NULL, "b"),
 #endif
-       PHPDBG_COMMAND_D_EX(oplog,        "usage: set oplog  <output>",          'O', set_oplog,        NULL, 0),
-       PHPDBG_COMMAND_D_EX(break,        "usage: set break [id] <on|off>",      'b', set_break,        NULL, 0),
+       PHPDBG_COMMAND_D_EX(oplog,        "usage: set oplog  <output>",          'O', set_oplog,        NULL, "s"),
+       PHPDBG_COMMAND_D_EX(break,        "usage: set break [id] <on|off>",      'b', set_break,        NULL, "lb"),
        PHPDBG_END_COMMAND
 };