From: Felipe Pena Date: Sun, 17 Nov 2013 21:01:41 +0000 (-0200) Subject: - Clean up command macros X-Git-Tag: php-5.6.0alpha1~110^2~259 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d054172a33a2732c3ff464f9cec4704a15a8f831;p=php - Clean up command macros - Added flag to specify no argument, required argument and optional argument --- diff --git a/config.m4 b/config.m4 index 248647a186..ee80daa25c 100644 --- a/config.m4 +++ b/config.m4 @@ -18,7 +18,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-I$abc_srcdir" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/phpdbg.c b/phpdbg.c index e467176dfb..1a4dbc17ad 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -31,97 +31,6 @@ void (*zend_execute_old)(zend_execute_data *execute_data TSRMLS_DC); void (*zend_execute_old)(zend_op_array *op_array TSRMLS_DC); #endif -const char* phpdbg_get_param_type(phpdbg_param_t *param TSRMLS_DC) { - switch (param->type) { - case EMPTY_PARAM: - return "empty"; - case ADDR_PARAM: - return "address"; - case NUMERIC_PARAM: - return "numeric"; - case METHOD_PARAM: - return "method"; - case FILE_PARAM: - return "file"; - case STR_PARAM: - return "string"; - - default: /* this is bad */ - return "unknown"; - } -} - -phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */ -{ - char *class_name, *func_name; - - if (len == 0) { - param->type = EMPTY_PARAM; - goto parsed; - } - - if (phpdbg_is_addr(str)) { - - param->addr = strtoul(str, 0, 16); - param->type = ADDR_PARAM; - goto parsed; - - } else if (phpdbg_is_numeric(str)) { - - param->num = strtol(str, NULL, 0); - param->type = NUMERIC_PARAM; - goto parsed; - - } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) { - - param->method.class = class_name; - param->method.name = func_name; - param->type = METHOD_PARAM; - goto parsed; - - } else { - const char *line_pos = strchr(str, ':'); - - if (line_pos && phpdbg_is_numeric(line_pos+1)) { - char path[MAXPATHLEN]; - - memcpy(path, str, line_pos - str); - path[line_pos - str] = 0; - - param->file.name = phpdbg_resolve_path(path TSRMLS_CC); - param->file.line = strtol(line_pos+1, NULL, 0); - param->type = FILE_PARAM; - goto parsed; - } - } - - param->str = estrndup(str, len); - param->len = len; - param->type = STR_PARAM; - -parsed: - phpdbg_debug("phpdbg_parse_param(\"%s\", %lu): %s", str, len, phpdbg_get_param_type(param TSRMLS_CC)); - return param->type; -} /* }}} */ - -void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */ -{ - switch (param->type) { - case FILE_PARAM: - efree(param->file.name); - break; - case METHOD_PARAM: - efree(param->method.class); - efree(param->method.name); - break; - case STR_PARAM: - efree(param->str); - break; - default: - break; - } -} /* }}} */ - static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ { pg->exec = NULL; diff --git a/phpdbg.h b/phpdbg.h index eb1aed5f43..99a5908606 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -53,6 +53,8 @@ # include #endif +#include "phpdbg_cmd.h" + #ifdef ZTS # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) #else @@ -99,48 +101,6 @@ #define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" #define PHPDBG_VERSION "0.0.2-dev" /* }}} */ -typedef struct _phpdbg_command_t phpdbg_command_t; - -/* {{{ Command and Parameter */ -typedef enum { - EMPTY_PARAM = 0, - ADDR_PARAM, - FILE_PARAM, - METHOD_PARAM, - STR_PARAM, - NUMERIC_PARAM -} phpdbg_param_type; - -typedef struct _phpdbg_param { - phpdbg_param_type type; - long num; - zend_ulong addr; - struct { - char *name; - long line; - } file; - struct { - char *class; - char *name; - } method; - char *str; - size_t len; -} phpdbg_param_t; - -typedef int (*phpdbg_command_handler_t)(phpdbg_param_t *param TSRMLS_DC); - -struct _phpdbg_command_t { - const char *name; /* Command name */ - size_t name_len; /* Command name length */ - const char *tip; /* Menu tip */ - size_t tip_len; /* Menu tip length */ - char alias; /* Alias */ - phpdbg_command_handler_t handler; /* Command handler */ - const phpdbg_command_t *subs; /* Sub Commands */ -}; - -#define PHPDBG_END_COMAND {NULL, 0, NULL, 0, '\0', NULL, NULL} - ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ char *exec; /* file to execute */ @@ -154,10 +114,6 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) zend_ulong flags; /* phpdbg flags */ FILE *oplog; /* opline log */ ZEND_END_MODULE_GLOBALS(phpdbg) - -phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC); -void phpdbg_clear_param(phpdbg_param_t * TSRMLS_DC); -const char* phpdbg_get_param_type(phpdbg_param_t *param TSRMLS_DC); /* }}} */ #endif /* PHPDBG_H */ diff --git a/phpdbg_break.h b/phpdbg_break.h index c5d5a5a80f..0f35c77f54 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -21,16 +21,9 @@ #define PHPDBG_BREAK_H #include "TSRM.h" +#include "phpdbg_cmd.h" -/** - * Command Declarators - */ -#define PHPDBG_BREAK_D(name, tip) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_break_##name, NULL} -#define PHPDBG_BREAK_EX_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_break_##name, NULL} -#define PHPDBG_BREAK(name) \ - int phpdbg_do_break_##name(phpdbg_param_t *param TSRMLS_DC) +#define PHPDBG_BREAK(name) PHPDBG_COMMAND(break_##name) /** * Printer Forward Declarations @@ -46,13 +39,13 @@ PHPDBG_BREAK(func); * Commands */ static const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_BREAK_EX_D(file, "specify breakpoint by file:line", 'F'), - PHPDBG_BREAK_EX_D(method, "specify breakpoint by class::method", 'm'), - PHPDBG_BREAK_EX_D(address, "specify breakpoint by address", 'a'), - PHPDBG_BREAK_EX_D(on, "specify breakpoint by expression", 'o'), - PHPDBG_BREAK_EX_D(lineno, "specify breakpoint by line of currently executing file", 'l'), - PHPDBG_BREAK_EX_D(func, "specify breakpoint by global function name", 'f'), - PHPDBG_END_COMAND + PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, 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(on, "specify breakpoint by expression", 'o', break_on, NULL, 1), + PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1), + PHPDBG_END_COMMAND }; #endif /* PHPDBG_BREAK_H */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c new file mode 100644 index 0000000000..479e678990 --- /dev/null +++ b/phpdbg_cmd.c @@ -0,0 +1,189 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#include "phpdbg_utils.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + switch (param->type) { + case EMPTY_PARAM: + return "empty"; + case ADDR_PARAM: + return "address"; + case NUMERIC_PARAM: + return "numeric"; + case METHOD_PARAM: + return "method"; + case FILE_PARAM: + return "file"; + case STR_PARAM: + return "string"; + default: /* this is bad */ + return "unknown"; + } +} + +phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + char *class_name, *func_name; + + if (len == 0) { + param->type = EMPTY_PARAM; + goto parsed; + } + + if (phpdbg_is_addr(str)) { + + param->addr = strtoul(str, 0, 16); + param->type = ADDR_PARAM; + goto parsed; + + } else if (phpdbg_is_numeric(str)) { + + param->num = strtol(str, NULL, 0); + param->type = NUMERIC_PARAM; + goto parsed; + + } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) { + + param->method.class = class_name; + param->method.name = func_name; + param->type = METHOD_PARAM; + goto parsed; + + } else { + const char *line_pos = strchr(str, ':'); + + if (line_pos && phpdbg_is_numeric(line_pos+1)) { + char path[MAXPATHLEN]; + + memcpy(path, str, line_pos - str); + path[line_pos - str] = 0; + + param->file.name = phpdbg_resolve_path(path TSRMLS_CC); + param->file.line = strtol(line_pos+1, NULL, 0); + param->type = FILE_PARAM; + goto parsed; + } + } + + param->str = estrndup(str, len); + param->len = len; + param->type = STR_PARAM; + +parsed: + phpdbg_debug("phpdbg_parse_param(\"%s\", %lu): %s", str, len, phpdbg_get_param_type(param TSRMLS_CC)); + return param->type; +} /* }}} */ + +void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + switch (param->type) { + case FILE_PARAM: + efree(param->file.name); + break; + case METHOD_PARAM: + efree(param->method.class); + efree(param->method.name); + break; + case STR_PARAM: + efree(param->str); + break; + default: + break; + } +} /* }}} */ + +int phpdbg_do_cmd( const phpdbg_command_t *command, + phpdbg_command_t **selected, + char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */ +{ + int rc = FAILURE; + + char *expr = NULL; +#ifndef _WIN32 + const char *cmd = strtok_r(cmd_line, " ", &expr); +#else + const char *cmd = strtok_s(cmd_line, " ", &expr); +#endif + size_t expr_len = (cmd != NULL) ? strlen(cmd) : 0; + + phpdbg_param_t *param = NULL; + + while (command && command->name && command->handler) { + if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0) + || (expr_len == 1 && command->alias && command->alias == cmd_line[0])) { + + param = emalloc(sizeof(phpdbg_param_t)); + + PHPDBG_G(last) = (phpdbg_command_t*) command; + + /* urm ... */ + if (PHPDBG_G(lparam)) { + //phpdbg_clear_param( + // PHPDBG_G(lparam) TSRMLS_CC); + //efree(PHPDBG_G(lparam)); + } + + phpdbg_parse_param( + expr, + (cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0, + param TSRMLS_CC); + + PHPDBG_G(lparam) = param; + + if (command->subs && param->type == STR_PARAM) { + if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) { + rc = SUCCESS; + /* because we can */ + phpdbg_clear_param(param TSRMLS_CC); + efree(param); + goto done; + } + } + + *selected = (phpdbg_command_t*) command; + + if (command->has_args == REQUIRED_ARG && param->type == EMPTY_PARAM) { + phpdbg_error("This command requires argument!"); + rc = FAILURE; + } else if (command->has_args == NO_ARG && param->type != EMPTY_PARAM) { + phpdbg_error("This command does not expect argument!"); + rc = FAILURE; + } else { + rc = command->handler(param TSRMLS_CC); + } + break; + } + ++command; + } + +done: + if (selected && param) { + phpdbg_debug( + "phpdbg_do_cmd(%s, \"%s\"): %d", + command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS)); + } + + return rc; +} /* }}} */ diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h new file mode 100644 index 0000000000..6b697aaccc --- /dev/null +++ b/phpdbg_cmd.h @@ -0,0 +1,105 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_CMD_H +#define PHPDBG_CMD_H + +#include "TSRM.h" + +typedef struct _phpdbg_command_t phpdbg_command_t; + +/* {{{ Command and Parameter */ +enum { + NO_ARG = 0, + REQUIRED_ARG, + OPTIONAL_ARG +}; + +typedef enum { + EMPTY_PARAM = 0, + ADDR_PARAM, + FILE_PARAM, + METHOD_PARAM, + STR_PARAM, + NUMERIC_PARAM +} phpdbg_param_type; + +typedef struct _phpdbg_param { + phpdbg_param_type type; + long num; + zend_ulong addr; + struct { + char *name; + long line; + } file; + struct { + char *class; + char *name; + } method; + char *str; + size_t len; +} phpdbg_param_t; + +typedef int (*phpdbg_command_handler_t)(phpdbg_param_t *param TSRMLS_DC); + +struct _phpdbg_command_t { + const char *name; /* Command name */ + size_t name_len; /* Command name length */ + const char *tip; /* Menu tip */ + size_t tip_len; /* Menu tip length */ + char alias; /* Alias */ + phpdbg_command_handler_t handler; /* Command handler */ + const phpdbg_command_t *subs; /* Sub Commands */ + char has_args; /* Accept args? */ +}; +/* }}} */ + +#define PHPDBG_STRL(s) s, sizeof(s)-1 + +/** + * Command Executor + */ +int phpdbg_do_cmd(const phpdbg_command_t*, phpdbg_command_t**, char *, size_t TSRMLS_DC); +phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC); +void phpdbg_clear_param(phpdbg_param_t * TSRMLS_DC); +const char* phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC); + +/** + * Command Declarators + */ +#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(name, tip, alias, children, has_args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, has_args} + +#define PHPDBG_COMMAND(name) int phpdbg_do_##name(phpdbg_param_t *param TSRMLS_DC) + +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} + +#define phpdbg_default_switch_case() \ + default:\ + phpdbg_error(\ + "Unsupported parameter type (%s) for command", \ + phpdbg_get_param_type(param TSRMLS_CC)); \ + break + +#endif /* PHPDBG_CMD_H */ diff --git a/phpdbg_help.h b/phpdbg_help.h index 445b84fc90..67a9191012 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -21,15 +21,10 @@ #define PHPDBG_HELP_H #include "TSRM.h" -#include "phpdbg_prompt.h" +#include "phpdbg.h" +#include "phpdbg_cmd.h" -/** - * Command Declarators - */ -#define PHPDBG_HELP_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_help_##name, NULL} -#define PHPDBG_HELP(name) \ - int phpdbg_do_help_##name(phpdbg_param_t *param TSRMLS_DC) +#define PHPDBG_HELP(name) PHPDBG_COMMAND(help_##name) /** * Helper Forward Declarations @@ -57,25 +52,25 @@ PHPDBG_HELP(oplog); * Commands */ static const phpdbg_command_t phpdbg_help_commands[] = { - PHPDBG_HELP_D(exec, "the execution context should be a valid path", 'e'), - PHPDBG_HELP_D(compile, "pre-compilation allows inspection of code before execution", 'c'), - PHPDBG_HELP_D(step, "stepping through execution allows inspection of the opline as it is executed", 's'), - PHPDBG_HELP_D(next, "continue executing while stepping or after breaking", 'n'), - PHPDBG_HELP_D(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r'), - PHPDBG_HELP_D(eval, "access to eval() allows you to affect the environment during execution", 'E'), - PHPDBG_HELP_D(until, "continue until the program reaches a source line different than the current one", 'u'), - PHPDBG_HELP_D(finish, "continue until the current function has returned", 'f'), - PHPDBG_HELP_D(leave, "continue until the current function is returning", 'L'), - PHPDBG_HELP_D(print, "printing allows inspection of the execution environment", 'p'), - PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'), - PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'), - PHPDBG_HELP_D(clear, "clearing breakpoints allows you to run code without interruption", 'c'), - PHPDBG_HELP_D(info, "quick access to useful information on the console", 'i'), - PHPDBG_HELP_D(back, "show debug backtrace information during execution", 't'), - PHPDBG_HELP_D(quiet, "be quiet during execution", 's'), - PHPDBG_HELP_D(list, "listing code gives you quick access to code while executing", 'l'), - PHPDBG_HELP_D(oplog, "keep clutter off the screen by sending oplogs to a file", 'O'), - {NULL, 0, 0} + PHPDBG_COMMAND_D_EX(exec, "the execution context should be a valid path", 'e', help_exec, NULL, 0), + PHPDBG_COMMAND_D_EX(compile, "pre-compilation allows inspection of code before execution", 'c', help_compile, NULL, 0), + PHPDBG_COMMAND_D_EX(step, "stepping through execution allows inspection of the opline as it is executed", 's', help_step, NULL, 0), + PHPDBG_COMMAND_D_EX(next, "continue executing while stepping or after breaking", 'n', help_next, NULL, 0), + PHPDBG_COMMAND_D_EX(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r', help_run, NULL, 0), + PHPDBG_COMMAND_D_EX(eval, "access to eval() allows you to affect the environment during execution", 'E', help_eval, NULL, 0), + PHPDBG_COMMAND_D_EX(until, "continue until the program reaches a source line different than the current one", 'u', help_until, NULL, 0), + PHPDBG_COMMAND_D_EX(finish, "continue until the current function has returned", 'f', help_finish, NULL, 0), + PHPDBG_COMMAND_D_EX(leave, "continue until the current function is returning", 'L', help_leave, NULL, 0), + PHPDBG_COMMAND_D_EX(print, "printing allows inspection of the execution environment", 'p', help_print, NULL, 0), + PHPDBG_COMMAND_D_EX(break, "breakpoints allow execution interruption", 'b', help_break, NULL, 0), + PHPDBG_COMMAND_D_EX(clean, "resetting the environment is useful while debugging and recompiling", 'X', help_clean, NULL, 0), + PHPDBG_COMMAND_D_EX(clear, "clearing breakpoints allows you to run code without interruption", 'c', help_clear, NULL, 0), + PHPDBG_COMMAND_D_EX(info, "quick access to useful information on the console", 'i', help_info, NULL, 0), + PHPDBG_COMMAND_D_EX(back, "show debug backtrace information during execution", 't', help_back, NULL, 0), + PHPDBG_COMMAND_D_EX(quiet, "be quiet during execution", 's', help_quiet, NULL, 0), + PHPDBG_COMMAND_D_EX(list, "listing code gives you quick access to code while executing", 'l', help_list, NULL, 0), + PHPDBG_COMMAND_D_EX(oplog, "keep clutter off the screen by sending oplogs to a file", 'O', help_oplog, NULL, 0), + PHPDBG_END_COMMAND }; #define phpdbg_help_header() \ diff --git a/phpdbg_info.c b/phpdbg_info.c index 631c8a4886..5f9e19629a 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -133,7 +133,7 @@ PHPDBG_INFO(classes) /* {{{ */ phpdbg_write("|-------- "); phpdbg_print_class_name(&pce TSRMLS_CC); phpdbg_writeln(EMPTY); - } while(pce = pce->parent); + } while ((pce = pce->parent)); } if ((*ce)->info.user.filename) { diff --git a/phpdbg_info.h b/phpdbg_info.h index 87da3ce0dd..5e88b731cb 100644 --- a/phpdbg_info.h +++ b/phpdbg_info.h @@ -20,21 +20,9 @@ #ifndef PHPDBG_INFO_H #define PHPDBG_INFO_H -#include "TSRM.h" -#include "phpdbg.h" -#include "phpdbg_prompt.h" -#include "phpdbg_utils.h" +#include "phpdbg_cmd.h" -/** - * Command Declarators - */ -#define PHPDBG_INFO_HANDLER(name) phpdbg_do_info_##name -#define PHPDBG_INFO_D(name, tip) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, PHPDBG_INFO_HANDLER(name), NULL} -#define PHPDBG_INFO_EX_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, PHPDBG_INFO_HANDLER(name), NULL} -#define PHPDBG_INFO(name) \ - int PHPDBG_INFO_HANDLER(name)(phpdbg_param_t *param TSRMLS_DC) +#define PHPDBG_INFO(name) PHPDBG_COMMAND(info_##name) PHPDBG_INFO(files); PHPDBG_INFO(classes); @@ -43,12 +31,12 @@ PHPDBG_INFO(error); PHPDBG_INFO(vars); static const phpdbg_command_t phpdbg_info_commands[] = { - PHPDBG_INFO_EX_D(files, "lists included files", 'F'), - PHPDBG_INFO_EX_D(classes, "lists loaded classes", 'c'), - PHPDBG_INFO_EX_D(funcs, "lists loaded classes", 'f'), - PHPDBG_INFO_EX_D(error, "show the last error", 'e'), - PHPDBG_INFO_EX_D(vars, "show active variables", 'v'), - PHPDBG_END_COMAND + PHPDBG_COMMAND_D_EX(files, "lists included files", 'F', info_files, NULL, 0), + PHPDBG_COMMAND_D_EX(classes, "lists loaded classes", 'c', info_classes, NULL, 0), + PHPDBG_COMMAND_D_EX(funcs, "lists loaded classes", 'f', info_funcs, NULL, 0), + PHPDBG_COMMAND_D_EX(error, "show the last error", 'e', info_error, NULL, 0), + PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_END_COMMAND }; #endif /* PHPDBG_INFO_H */ diff --git a/phpdbg_list.h b/phpdbg_list.h index e186bd3d9f..19a015105f 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -21,20 +21,10 @@ #define PHPDBG_LIST_H #include "TSRM.h" -#include "phpdbg_prompt.h" -#include "phpdbg_utils.h" - -/** - * Command Declarators - */ -#define PHPDBG_LIST_HANDLER(name) phpdbg_do_list_##name -#define PHPDBG_LIST_D(name, tip) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_list_##name, NULL} -#define PHPDBG_LIST_EX_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_list_##name, NULL} -#define PHPDBG_LIST(name) \ - int PHPDBG_LIST_HANDLER(name)(phpdbg_param_t *param TSRMLS_DC) +#include "phpdbg_cmd.h" +#define PHPDBG_LIST(name) PHPDBG_COMMAND(list_##name) +#define PHPDBG_LIST_HANDLER(name) PHPDBG_COMMAND_HANDLER(list_##name) PHPDBG_LIST(lines); PHPDBG_LIST(class); @@ -46,11 +36,11 @@ void phpdbg_list_function(const zend_function* TSRMLS_DC); void phpdbg_list_file(const char*, long, long, int TSRMLS_DC); static const phpdbg_command_t phpdbg_list_commands[] = { - PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'), - PHPDBG_LIST_EX_D(class, "lists the specified class", 'c'), - PHPDBG_LIST_EX_D(method, "lists the specified method", 'm'), - PHPDBG_LIST_EX_D(func, "lists the specified function", 'f'), - PHPDBG_END_COMAND + 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_END_COMMAND }; #endif /* PHPDBG_LIST_H */ diff --git a/phpdbg_print.c b/phpdbg_print.c index 9a4a1585d6..3e29ae6487 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -21,6 +21,7 @@ #include "phpdbg_print.h" #include "phpdbg_utils.h" #include "phpdbg_opcode.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -50,7 +51,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) phpdbg_writeln( "\t#%d-%d %s::%s() %s", op_array->line_start, op_array->line_end, - method->common.scope->name, + method->common.scope->name, method->common.function_name, op_array->filename ? op_array->filename : "unknown"); } else { @@ -60,20 +61,20 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) method->common.function_name ? method->common.function_name : "{main}", op_array->filename ? op_array->filename : "unknown"); } - - + + do { const char *decode = phpdbg_decode_opcode(opline->opcode); if (decode != NULL) { phpdbg_writeln( - "\t\t#%lu\t%p %s", opline->lineno, opline, decode); + "\t\t#%lu\t%p %s", opline->lineno, opline, decode); } else phpdbg_error("\tFailed to decode opline @ %ld", opline); - + opline++; } while (++opcode < end); } } break; - + default: { if (method->common.scope) { phpdbg_writeln( @@ -92,7 +93,7 @@ PHPDBG_PRINT(exec) /* {{{ */ if (!PHPDBG_G(ops)) { phpdbg_compile(TSRMLS_C); } - + if (PHPDBG_G(ops)) { phpdbg_notice( "Context %s", PHPDBG_G(exec)); @@ -102,33 +103,33 @@ PHPDBG_PRINT(exec) /* {{{ */ } else { phpdbg_error("No execution context set"); } - + return SUCCESS; } /* }}} */ PHPDBG_PRINT(class) /* {{{ */ { zend_class_entry **ce; - + switch (param->type) { case STR_PARAM: { if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { phpdbg_notice( - "%s %s: %s", - ((*ce)->type == ZEND_USER_CLASS) ? + "%s %s: %s", + ((*ce)->type == ZEND_USER_CLASS) ? "User" : "Internal", - ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? + ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? "Abstract Class" : - "Class", + "Class", (*ce)->name); - + phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table)); if (zend_hash_num_elements(&(*ce)->function_table)) { HashPosition position; zend_function *method; - + for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position); zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS; zend_hash_move_forward_ex(&(*ce)->function_table, &position)) { @@ -140,7 +141,7 @@ PHPDBG_PRINT(class) /* {{{ */ "The class %s could not be found", param->str); } } break; - + phpdbg_default_switch_case(); } @@ -159,26 +160,26 @@ PHPDBG_PRINT(method) /* {{{ */ if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { phpdbg_notice( - "%s Method %s", - (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + "%s Method %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", fbc->common.function_name); - + phpdbg_print_function_helper(fbc TSRMLS_CC); } else { phpdbg_error( "The method %s could not be found", param->method.name); } - + efree(lcname); } else { phpdbg_error( "The class %s could not be found", param->method.class); } } break; - + phpdbg_default_switch_case(); } - + return SUCCESS; } /* }}} */ @@ -190,7 +191,7 @@ PHPDBG_PRINT(func) /* {{{ */ zend_function* fbc; const char *func_name = param->str; size_t func_name_len = param->len; - char *lcname; + char *lcname; /* search active scope if begins with period */ if (func_name[0] == '.') { if (EG(scope)) { @@ -209,25 +210,25 @@ PHPDBG_PRINT(func) /* {{{ */ } else { func_table = EG(function_table); } - + lcname = zend_str_tolower_dup(func_name, func_name_len); - + if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { phpdbg_notice( "%s %s %s", - (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", (fbc->common.scope) ? "Method" : "Function", fbc->common.function_name); - + phpdbg_print_function_helper(fbc TSRMLS_CC); } else { phpdbg_error( "The function %s could not be found", func_name); } - + efree(lcname); } break; - + phpdbg_default_switch_case(); } diff --git a/phpdbg_print.h b/phpdbg_print.h index 40acfe1b6f..a78e9cd6fd 100644 --- a/phpdbg_print.h +++ b/phpdbg_print.h @@ -20,16 +20,9 @@ #ifndef PHPDBG_PRINT_H #define PHPDBG_PRINT_H -#include "TSRM.h" -#include "phpdbg_prompt.h" +#include "phpdbg_cmd.h" -/** - * Command Declarators - */ -#define PHPDBG_PRINT_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_print_##name, NULL} -#define PHPDBG_PRINT(name) \ - int phpdbg_do_print_##name(phpdbg_param_t *param TSRMLS_DC) +#define PHPDBG_PRINT(name) PHPDBG_COMMAND(print_##name) /** * Printer Forward Declarations @@ -44,12 +37,12 @@ PHPDBG_PRINT(func); * Commands */ static const phpdbg_command_t phpdbg_print_commands[] = { - PHPDBG_PRINT_D(exec, "print execution context instructions", 'e'), - PHPDBG_PRINT_D(opline, "print the current opline information", 'o'), - PHPDBG_PRINT_D(class, "print out the instructions in the specified class", 'c'), - PHPDBG_PRINT_D(method, "print out the instructions in the specified method", 'm'), - PHPDBG_PRINT_D(func, "print out the instructions in the specified function", 'f'), - PHPDBG_END_COMAND + PHPDBG_COMMAND_D_EX(exec, "print execution context instructions", 'e', print_exec, NULL, 0), + PHPDBG_COMMAND_D_EX(opline, "print the current opline information", '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_END_COMMAND }; #endif /* PHPDBG_PRINT_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 844ff492f9..d8c53ddf26 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -30,6 +30,8 @@ #include "phpdbg_opcode.h" #include "phpdbg_list.h" #include "phpdbg_utils.h" +#include "phpdbg_prompt.h" +#include "phpdbg_cmd.h" /* {{{ forward declarations */ static PHPDBG_COMMAND(exec); @@ -56,28 +58,28 @@ static PHPDBG_COMMAND(quit); /* }}} */ /* {{{ command declarations */ static const phpdbg_command_t phpdbg_prompt_commands[] = { - PHPDBG_COMMAND_EX_D(exec, "set execution context", 'e'), - PHPDBG_COMMAND_EX_D(compile, "attempt to pre-compile execution context", 'c'), - PHPDBG_COMMAND_EX_D(step, "step through execution", 's'), - PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'), - PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'), - PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'), - PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'), - PHPDBG_COMMAND_EX_D(finish, "continue past the end of the stack", 'f'), - PHPDBG_COMMAND_EX_D(leave, "continue until the end of the stack", 'L'), - PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands), - PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands), - PHPDBG_COMMAND_EX_D(back, "show trace", 't'), - PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands), - PHPDBG_COMMANDS_D(info, "displays some informations", 'i', phpdbg_info_commands), - PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'), - PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'), - PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands), - PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'), - PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'), - PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'), - PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'), - PHPDBG_END_COMAND + PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, 1), + PHPDBG_COMMAND_D(compile, "attempt to pre-compile execution context", 'c', NULL, 0), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 1), + 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(until, "continue until reaches next 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, 1), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1), + PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), + 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(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, 1), + PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1), + PHPDBG_COMMAND_D(aliases, "show alias list", 'a', NULL, 0), + PHPDBG_COMMAND_D(oplog, "sets oplog output", 'O', NULL, 1), + PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_END_COMMAND }; /* }}} */ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -350,12 +352,12 @@ static PHPDBG_COMMAND(run) /* {{{ */ if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } - + zend_try { /* last chance ... */ zend_activate_auto_globals(TSRMLS_C); } zend_end_try(); - + zend_try { zend_execute( EG(active_op_array) TSRMLS_CC); @@ -742,73 +744,6 @@ static PHPDBG_COMMAND(list) /* {{{ */ return SUCCESS; } /* }}} */ -int phpdbg_do_cmd( const phpdbg_command_t *command, - phpdbg_command_t **selected, - char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */ -{ - int rc = FAILURE; - - char *expr = NULL; -#ifndef _WIN32 - const char *cmd = strtok_r(cmd_line, " ", &expr); -#else - const char *cmd = strtok_s(cmd_line, " ", &expr); -#endif - size_t expr_len = (cmd != NULL) ? strlen(cmd) : 0; - - phpdbg_param_t *param = NULL; - - while (command && command->name && command->handler) { - if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0) - || (expr_len == 1 && command->alias && command->alias == cmd_line[0])) { - - param = emalloc(sizeof(phpdbg_param_t)); - - PHPDBG_G(last) = (phpdbg_command_t*) command; - - /* urm ... */ - if (PHPDBG_G(lparam)) { - //phpdbg_clear_param( - // PHPDBG_G(lparam) TSRMLS_CC); - //efree(PHPDBG_G(lparam)); - } - - phpdbg_parse_param( - expr, - (cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0, - param TSRMLS_CC); - - PHPDBG_G(lparam) = param; - - if (command->subs && param->type == STR_PARAM) { - if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) { - rc = SUCCESS; - /* because we can */ - phpdbg_clear_param(param TSRMLS_CC); - efree(param); - goto done; - } - } - - *selected = (phpdbg_command_t*) command; - - rc = command->handler(param TSRMLS_CC); - - break; - } - ++command; - } - -done: - if (selected && param) { - phpdbg_debug( - "phpdbg_do_cmd(%s, \"%s\"): %d", - command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS)); - } - - return rc; -} /* }}} */ - int phpdbg_interactive(TSRMLS_D) /* {{{ */ { size_t cmd_len; diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 65148e3497..ce2864751b 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -25,25 +25,6 @@ */ #define PHPDBG_MAX_CMD 500 -#define PHPDBG_STRL(s) s, sizeof(s)-1 - -/** - * Command Executor - */ -int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_command_t **selected, char *cmd_line, size_t cmd_len TSRMLS_DC); - -/** - * Command Declarators - */ -#define PHPDBG_COMMAND_D(name, tip) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_##name, NULL} -#define PHPDBG_COMMAND_EX_D(name, tip, alias) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, NULL} -#define PHPDBG_COMMANDS_D(name, tip, alias, children) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children} -#define PHPDBG_COMMAND(name) \ - int phpdbg_do_##name(phpdbg_param_t *param TSRMLS_DC) - void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC); void phpdbg_welcome(zend_bool cleaning TSRMLS_DC); int phpdbg_interactive(TSRMLS_D); @@ -57,11 +38,4 @@ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC); void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC); #endif -#define phpdbg_default_switch_case() \ - default:\ - phpdbg_error(\ - "Unsupported parameter type (%s) for command", \ - phpdbg_get_param_type(param TSRMLS_CC)); \ - break - #endif /* PHPDBG_PROMPT_H */