diff options
author | krakjoe <joe.watkins@live.co.uk> | 2014-02-19 20:18:49 +0000 |
---|---|---|
committer | krakjoe <joe.watkins@live.co.uk> | 2014-02-19 20:18:49 +0000 |
commit | e2fcc870e34510dc4cc47ad69d77b28ae9eb21df (patch) | |
tree | d70f3f3a86398c0c1715a184af7a3c8ae7e6c7f7 /phpdbg_cmd.c | |
parent | 996182993da1c35e8c35a3188b4c1adb764320f8 (diff) | |
download | php-git-e2fcc870e34510dc4cc47ad69d77b28ae9eb21df.tar.gz |
work on lexer to be more permissive (accept moar strings)
work on parameter parsing and command resolution
work on error reporting for failed arguments
update most commands
move quiet to set quiet
move set break on/off to set breaks on/off
keep set break for set break <id> <on/off>
update help accordingly
Diffstat (limited to 'phpdbg_cmd.c')
-rw-r--r-- | phpdbg_cmd.c | 201 |
1 files changed, 111 insertions, 90 deletions
diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index b678d393ab..4e6ef048b8 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -26,6 +26,23 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +static inline const char *phpdbg_command_name(const phpdbg_command_t *command, char *buffer) { + size_t pos = 0; + + if (command->parent) { + memcpy(&buffer[pos], command->parent->name, command->parent->name_len); + pos += command->parent->name_len; + memcpy(&buffer[pos], " ", sizeof(" ")-1); + pos += (sizeof(" ")-1); + } + + memcpy(&buffer[pos], command->name, command->name_len); + pos += command->name_len; + buffer[pos] = 0; + + return buffer; +} + PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { switch (param->type) { @@ -493,115 +510,87 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { if (command && command->args) { + char buffer[128] = {0,}; const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; - size_t expected = strlen(command->args), - received = 0L; + size_t least = 0L, + received = 0L, + current = 0L; zend_bool optional = 0; - if (*arg == '|') { - expected--; - optional = 1; + /* check for arg spec */ + if (!(arg) || !(*arg)) + return SUCCESS; + + least = 0L; + + /* count least amount of arguments */ + while (arg && *arg) { + if (arg[0] == '|') { + break; + } + least++; arg++; } - if (arg && !top && !optional) { - asprintf(why, - "%s expected arguments and received none", command->name); - return FAILURE; - } - - while (top && arg) { + arg = command->args; + +#define verify_arg(e, a, t) if (!(a)) { \ + if (!optional) { \ + asprintf(why, \ + "%s expected %s and got nothing at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e), \ + current); \ + return FAILURE;\ + } \ +} else if ((a)->type != (t)) { \ + asprintf(why, \ + "%s expected %s and got %s at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e),\ + phpdbg_get_param_type((a) TSRMLS_CC), \ + current); \ + return FAILURE; \ +} + while (arg) { + current++; + switch (*arg) { - case '|': { - expected--; + case '|': { + current--; optional = 1; arg++; } continue; - case 'i': if (top->type != STR_PARAM) { - asprintf(why, - "%s expected raw input and got %s at parameter %lu", - 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 %lu", - 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 %lu", - 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 %lu", - 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 %lu", - 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 %lu", - 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 %lu", - 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 %lu", - 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 %lu", - command->name, - (command->args - arg) + 1); - return FAILURE; - } break; + case 'i': verify_arg("raw input", top, STR_PARAM); break; + case 's': verify_arg("string", top, STR_PARAM); break; + case 'n': verify_arg("number", top, NUMERIC_PARAM); break; + case 'm': verify_arg("method", top, METHOD_PARAM); break; + case 'a': verify_arg("address", top, ADDR_PARAM); break; + case 'f': verify_arg("file:line", top, FILE_PARAM); break; + case 'c': verify_arg("condition", top, COND_PARAM); break; + case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; case '*': { /* do nothing */ } break; } - top = top->next; + + if (top ) { + top = top->next; + } else break; + received++; arg++; } - if ((received < expected) && (arg && *arg) && !optional) { +#undef verify_arg + + if ((received < least)) { asprintf(why, - "%s expected %lu arguments (%s) and received %lu", - command->name, - expected, + "%s expected at least %lu arguments (%s) and received %lu", + phpdbg_command_name(command, buffer), + least, command->args, received); return FAILURE; @@ -627,15 +616,21 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * matches++; } } else { + /* match full command name */ if (memcmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { matched[matches] = command; matches++; + + /* exact match */ + if (name->len == command->name_len) + break; } else break; } } } + command++; } @@ -655,10 +650,36 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } break; default: { + char *list = NULL; + zend_uint it = 0; + size_t pos = 0; + + while (it < matches) { + if (!list) { + list = malloc( + matched[it]->name_len + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } else { + list = realloc(list, + (pos + matched[it]->name_len) + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } + memcpy(&list[pos], matched[it]->name, matched[it]->name_len); + pos += matched[it]->name_len; + if ((it+1) < matches) { + memcpy(&list[pos], ", ", sizeof(", ")-1); + pos += (sizeof(", ") - 1); + } + + list[pos] = 0; + it++; + } + asprintf( why, - "The command %s is ambigious, matching %lu commands", - name->str, matches); + "The command %s is ambigious, matching %lu commands (%s)", + name->str, matches, list); + free(list); } return NULL; } |