From 6a3194a47d867a8fe54f7d94111bf3e31ed2ea6d Mon Sep 17 00:00:00 2001 From: krakjoe Date: Thu, 14 Nov 2013 15:46:06 +0000 Subject: [PATCH] move listing commands out to their own command list add TSRMLS_CC in clear_param for consistency --- phpdbg_list.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_list.h | 24 ++++++++++++ phpdbg_prompt.c | 64 ++++++++---------------------- phpdbg_utils.c | 2 +- phpdbg_utils.h | 1 + 5 files changed, 145 insertions(+), 48 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index ae0d5c6c58..2e4f5e79b3 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -29,6 +29,108 @@ #include "phpdbg_list.h" #include "phpdbg_utils.h" +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +static inline void i_phpdbg_list_func(const char *str TSRMLS_DC) +{ + HashTable *func_table = EG(function_table); + zend_function* fbc; + const char *func_name = str; + size_t func_name_len = strlen(str); + + /* search active scope if begins with period */ + if (func_name[0] == '.') { + if (EG(scope)) { + func_name++; + func_name_len--; + + func_table = &EG(scope)->function_table; + } else { + phpdbg_error("No active class"); + return; + } + } else if (!EG(function_table)) { + phpdbg_error("No function table loaded"); + return; + } else { + func_table = EG(function_table); + } + + if (zend_hash_find(func_table, func_name, func_name_len+1, + (void**)&fbc) == SUCCESS) { + phpdbg_list_function(fbc TSRMLS_CC); + } else { + phpdbg_error("Function %s not found", func_name); + } +} + +PHPDBG_LIST(lines) /* {{{ */ +{ + phpdbg_param_t param; + int type = phpdbg_parse_param( + expr, expr_len, ¶m TSRMLS_CC); + + switch (type) { + case NUMERIC_PARAM: + case EMPTY_PARAM: { + if (PHPDBG_G(exec) || zend_is_executing(TSRMLS_C)) { + if (type == EMPTY_PARAM) { + phpdbg_list_file(phpdbg_current_file(TSRMLS_C), 0, 0 TSRMLS_CC); + } else phpdbg_list_file(phpdbg_current_file(TSRMLS_C), param.num, 0 TSRMLS_CC); + } else phpdbg_error("Not executing, and execution context not set"); + } break; + + default: + phpdbg_error("Unsupported parameter type (%d) for command", type); + } + + phpdbg_clear_param(type, ¶m TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +PHPDBG_LIST(func) /* {{{ */ +{ + phpdbg_param_t param; + int type = phpdbg_parse_param( + expr, expr_len, ¶m TSRMLS_CC); + + if (type == STR_PARAM) { + i_phpdbg_list_func( + param.str TSRMLS_CC); + } + + phpdbg_clear_param(type, ¶m TSRMLS_CC); + + return SUCCESS; +} /* }}} */ + +void phpdbg_list_dispatch(int type, phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + switch (type) { + case NUMERIC_PARAM: + case EMPTY_PARAM: { + if (PHPDBG_G(exec) || zend_is_executing(TSRMLS_C)) { + if (type == EMPTY_PARAM) { + phpdbg_list_file(phpdbg_current_file(TSRMLS_C), 0, 0 TSRMLS_CC); + } else phpdbg_list_file(phpdbg_current_file(TSRMLS_C), param->num, 0 TSRMLS_CC); + } else phpdbg_error("Not executing, and execution context not set"); + } break; + + case FILE_PARAM: + phpdbg_list_file(param->file.name, param->file.line, 0 TSRMLS_CC); + break; + + case STR_PARAM: { + i_phpdbg_list_func(param->str TSRMLS_CC); + } break; + + default: + phpdbg_error("Unsupported input type (%d) for command", type); + break; + } +} /* }}} */ + void phpdbg_list_file(const char *filename, long count, long offset TSRMLS_DC) /* {{{ */ { unsigned char *mem, *pos, *last_pos, *end_pos; diff --git a/phpdbg_list.h b/phpdbg_list.h index 2a2587504a..96323fc0ea 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -20,7 +20,31 @@ #ifndef PHPDBG_LIST_H #define PHPDBG_LIST_H +#include "TSRM.h" +#include "phpdbg_prompt.h" +#include "phpdbg_utils.h" + +/** + * Command Declarators + */ +#define PHPDBG_LIST_D(name, tip) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_list_##name} +#define PHPDBG_LIST_EX_D(name, tip, alias) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_list_##name} +#define PHPDBG_LIST(name) \ + int phpdbg_do_list_##name(const char *expr, size_t expr_len TSRMLS_DC) + +PHPDBG_LIST(lines); +PHPDBG_LIST(func); + void phpdbg_list_function(const zend_function* TSRMLS_DC); void phpdbg_list_file(const char*, long, long TSRMLS_DC); +void phpdbg_list_dispatch(int type, phpdbg_param_t *param TSRMLS_DC); + +static const phpdbg_command_t phpdbg_list_commands[] = { + PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'), + PHPDBG_LIST_EX_D(func, "lists the specified function", 'f'), + {NULL, 0, 0} +}; #endif /* PHPDBG_LIST_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 7d20580922..f133c24ec0 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -350,8 +350,8 @@ static PHPDBG_COMMAND(print) /* {{{ */ static PHPDBG_COMMAND(break) /* {{{ */ { phpdbg_param_t param; - char *line_pos; - + int type; + if (expr_len == 0) { phpdbg_error("No expression found"); return FAILURE; @@ -362,7 +362,7 @@ static PHPDBG_COMMAND(break) /* {{{ */ return SUCCESS; } - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) { case ADDR_PARAM: phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC); break; @@ -381,7 +381,8 @@ static PHPDBG_COMMAND(break) /* {{{ */ default: break; } - phpdbg_clear_param(¶m); + + phpdbg_clear_param(type, ¶m TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -503,51 +504,20 @@ static PHPDBG_COMMAND(quiet) { /* {{{ */ static PHPDBG_COMMAND(list) /* {{{ */ { - if (phpdbg_is_empty(expr) || phpdbg_is_numeric(expr)) { - long offset = 0, count = strtol(expr, NULL, 0); - const char *filename = PHPDBG_G(exec); - - if (zend_is_executing(TSRMLS_C)) { - filename = zend_get_executed_filename(TSRMLS_C); - offset = zend_get_executed_lineno(TSRMLS_C); - } else if (!filename) { - phpdbg_error("No file to list"); - return SUCCESS; - } - - phpdbg_list_file(filename, count, offset TSRMLS_CC); - } else { - HashTable *func_table = EG(function_table); - zend_function* fbc; - const char *func_name = expr; - size_t func_name_len = expr_len; - - /* search active scope if begins with period */ - if (func_name[0] == '.') { - if (EG(scope)) { - func_name++; - func_name_len--; - - func_table = &EG(scope)->function_table; - } else { - phpdbg_error("No active class"); - return FAILURE; - } - } else if (!EG(function_table)) { - phpdbg_error("No function table loaded"); - return SUCCESS; - } else { - func_table = EG(function_table); - } - - if (zend_hash_find(func_table, func_name, func_name_len+1, - (void**)&fbc) == SUCCESS) { - phpdbg_list_function(fbc TSRMLS_CC); - } else { - phpdbg_error("Function %s not found", func_name); - } + phpdbg_param_t param; + int type = 0; + + /* allow advanced listers to run */ + if (phpdbg_do_cmd(phpdbg_list_commands, (char*)expr, expr_len TSRMLS_CC) == SUCCESS) { + return SUCCESS; } + phpdbg_list_dispatch( + phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC), + ¶m TSRMLS_CC); + + phpdbg_clear_param(type, ¶m TSRMLS_CC); + return SUCCESS; } /* }}} */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 95a49e3e54..91e7ec2b50 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -141,7 +141,7 @@ int phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS return STR_PARAM; } /* }}} */ -void phpdbg_clear_param(int type, phpdbg_param_t *param) /* {{{ */ +void phpdbg_clear_param(int type, phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { switch (type) { case FILE_PARAM: diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 24bb09bf53..9ae3f8d136 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -55,6 +55,7 @@ typedef union _phpdbg_param { } phpdbg_param_t; int phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC); +void phpdbg_clear_param(int, phpdbg_param_t * TSRMLS_DC); const char *phpdbg_current_file(TSRMLS_D); char *phpdbg_resolve_path(const char* TSRMLS_DC); -- 2.50.1