From: krakjoe Date: Sat, 16 Nov 2013 14:34:49 +0000 (+0000) Subject: make handlers take phpdbg_param_t X-Git-Tag: php-5.6.0alpha1~110^2~287 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cf58c7cea376be23c81d2d3f6505a177cd811862;p=php make handlers take phpdbg_param_t --- diff --git a/phpdbg.c b/phpdbg.c index 40a2432b50..a8e5c82ba9 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -129,8 +129,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->vmret = 0; pg->bp_count = 0; pg->last = NULL; - pg->last_params = NULL; - pg->last_params_len = 0; + pg->lparam = NULL; pg->flags = PHPDBG_DEFAULT_FLAGS; pg->oplog = NULL; } /* }}} */ @@ -232,35 +231,37 @@ static PHP_FUNCTION(phpdbg_break) long type; char *expr = NULL; zend_uint expr_len = 0; + phpdbg_param_t param; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &type, &expr, &expr_len) == FAILURE) { return; } - + + phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC); + switch (type) { case METHOD_PARAM: - phpdbg_do_break_method( - expr, expr_len TSRMLS_CC); + phpdbg_do_break_method(¶m TSRMLS_CC); break; case FILE_PARAM: - phpdbg_do_break_file( - expr, expr_len TSRMLS_CC); + phpdbg_do_break_file(¶m TSRMLS_CC); break; case NUMERIC_PARAM: - phpdbg_do_break_lineno( - expr, expr_len TSRMLS_CC); + phpdbg_do_break_lineno(¶m TSRMLS_CC); break; case STR_PARAM: - phpdbg_do_break_func( - expr, expr_len TSRMLS_CC); + phpdbg_do_break_func(¶m TSRMLS_CC); break; default: zend_error( E_WARNING, "unrecognized parameter type %ld", type); } + + phpdbg_clear_param(¶m TSRMLS_CC); + } else if (EG(current_execute_data) && EG(active_op_array)) { zend_ulong opline_num = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes); diff --git a/phpdbg.h b/phpdbg.h index 39d55d1a5b..2d82db35cf 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -97,21 +97,6 @@ typedef struct _phpdbg_command_t phpdbg_command_t; -ZEND_BEGIN_MODULE_GLOBALS(phpdbg) - HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ - char *exec; /* file to execute */ - size_t exec_len; /* size of exec */ - zend_op_array *ops; /* op_array */ - zval *retval; /* return value */ - int bp_count; /* breakpoint count */ - int vmret; /* return from last opcode handler execution */ - phpdbg_command_t *last; /* last command */ - const char *last_params; /* last expression */ - size_t last_params_len; /* last expression length */ - zend_ulong flags; /* phpdbg flags */ - FILE *oplog; /* opline log */ -ZEND_END_MODULE_GLOBALS(phpdbg) - /* {{{ Command and Parameter */ typedef enum { EMPTY_PARAM = 0, @@ -138,7 +123,7 @@ typedef struct _phpdbg_param { size_t len; } phpdbg_param_t; -typedef int (*phpdbg_command_handler_t)(const char* expr, size_t expr_len TSRMLS_DC); +typedef int (*phpdbg_command_handler_t)(phpdbg_param_t *param TSRMLS_DC); struct _phpdbg_command_t { const char *name; /* Command name */ @@ -147,7 +132,21 @@ struct _phpdbg_command_t { size_t tip_len; /* Menu tip length */ char alias; /* Alias */ phpdbg_command_handler_t handler; /* Command handler */ -}; +}; + +ZEND_BEGIN_MODULE_GLOBALS(phpdbg) + HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ + char *exec; /* file to execute */ + size_t exec_len; /* size of exec */ + zend_op_array *ops; /* op_array */ + zval *retval; /* return value */ + int bp_count; /* breakpoint count */ + int vmret; /* return from last opcode handler execution */ + phpdbg_command_t *last; /* last command */ + phpdbg_param_t *lparam; /* last param */ + 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); diff --git a/phpdbg_break.c b/phpdbg_break.c index 035d71ac89..03d87f6e19 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -28,121 +28,105 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); PHPDBG_BREAK(file) /* {{{ */ { - phpdbg_param_t param; - - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case EMPTY_PARAM: phpdbg_error("No expression provided"); break; case FILE_PARAM: - phpdbg_set_breakpoint_file(param.file.name, param.file.line TSRMLS_CC); + phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break; default: - phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); + phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); break; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ PHPDBG_BREAK(method) /* {{{ */ { - phpdbg_param_t param; - - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case EMPTY_PARAM: phpdbg_error("No expression provided"); break; case METHOD_PARAM: - phpdbg_set_breakpoint_method(param.method.class, param.method.name TSRMLS_CC); + phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); break; default: - phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); + phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); break; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ PHPDBG_BREAK(address) /* {{{ */ { - phpdbg_param_t param; - - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case EMPTY_PARAM: phpdbg_error("No expression provided"); break; case ADDR_PARAM: - phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC); + phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); break; default: - phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); - break; + phpdbg_error( + "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ PHPDBG_BREAK(on) /* {{{ */ { - if (expr_len == 0) { - phpdbg_error("No expression provided!"); + if (param->type == STR_PARAM) { + phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); } else { - phpdbg_set_breakpoint_expression(expr, expr_len TSRMLS_CC); + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } return SUCCESS; } /* }}} */ PHPDBG_BREAK(lineno) /* {{{ */ { - phpdbg_param_t param; - if (!PHPDBG_G(exec)) { phpdbg_error("Not file context found!"); return SUCCESS; } - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case EMPTY_PARAM: phpdbg_error("No expression provided!"); break; case NUMERIC_PARAM: - phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param.num TSRMLS_CC); + phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); break; default: - phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); - break; + phpdbg_error( + "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ PHPDBG_BREAK(func) /* {{{ */ { - phpdbg_param_t param; - - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case EMPTY_PARAM: phpdbg_error("No expression provided!"); break; case STR_PARAM: - phpdbg_set_breakpoint_symbol(param.str TSRMLS_CC); + phpdbg_set_breakpoint_symbol(param->str TSRMLS_CC); break; default: - phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); + phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); break; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ diff --git a/phpdbg_break.h b/phpdbg_break.h index 23677e75da..cb29b7a0d6 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -30,7 +30,7 @@ #define PHPDBG_BREAK_EX_D(name, tip, alias) \ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_break_##name} #define PHPDBG_BREAK(name) \ - int phpdbg_do_break_##name(const char *expr, size_t expr_len TSRMLS_DC) + int phpdbg_do_break_##name(phpdbg_param_t *param TSRMLS_DC) /** * Printer Forward Declarations diff --git a/phpdbg_help.h b/phpdbg_help.h index 9f86848dca..1e39420324 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -29,7 +29,7 @@ #define PHPDBG_HELP_D(name, tip) \ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_help_##name} #define PHPDBG_HELP(name) \ - int phpdbg_do_help_##name(const char *expr, size_t expr_len TSRMLS_DC) + int phpdbg_do_help_##name(phpdbg_param_t *param TSRMLS_DC) /** * Helper Forward Declarations diff --git a/phpdbg_list.c b/phpdbg_list.c index e85074be0e..a4c3d1272d 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -66,41 +66,33 @@ static inline void i_phpdbg_list_func(const char *str TSRMLS_DC) PHPDBG_LIST(lines) /* {{{ */ { - phpdbg_param_t param; - - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case NUMERIC_PARAM: case EMPTY_PARAM: { if (PHPDBG_G(exec) || zend_is_executing(TSRMLS_C)) { - if (param.type == EMPTY_PARAM) { + if (param->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_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 (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); + phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ PHPDBG_LIST(func) /* {{{ */ { - phpdbg_param_t param; - - if (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC) == STR_PARAM) { + if (param->type == STR_PARAM) { i_phpdbg_list_func( - param.str TSRMLS_CC); + param->str TSRMLS_CC); } else { phpdbg_error( - "Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC)); + "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC)); } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ diff --git a/phpdbg_list.h b/phpdbg_list.h index bb8f34cbfc..8829d7f6cc 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -32,7 +32,7 @@ #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) + int phpdbg_do_list_##name(phpdbg_param_t *param TSRMLS_DC) PHPDBG_LIST(lines); PHPDBG_LIST(func); diff --git a/phpdbg_print.c b/phpdbg_print.c index 952b71f9c7..4d66e4a644 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -90,8 +90,8 @@ PHPDBG_PRINT(class) /* {{{ */ { zend_class_entry **ce; - if (expr && expr_len > 0L) { - if (zend_lookup_class(expr, strlen(expr), &ce TSRMLS_CC) == SUCCESS) { + if (param->type == STR_PARAM) { + if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { phpdbg_notice( "%s %s: %s", ((*ce)->type == ZEND_USER_CLASS) ? @@ -115,10 +115,14 @@ PHPDBG_PRINT(class) /* {{{ */ } } } else { - phpdbg_error("Cannot find class %s", expr); + phpdbg_error( + "Cannot find class %s", param->str); + return FAILURE; } } else { - phpdbg_error("No class name provided!"); + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } return SUCCESS; @@ -126,51 +130,52 @@ PHPDBG_PRINT(class) /* {{{ */ PHPDBG_PRINT(method) /* {{{ */ { - if (expr && expr_len > 0L) { - char *class_name = NULL; - char *func_name = NULL; + int result = SUCCESS; + + if (param->type == METHOD_PARAM) { + zend_class_entry **ce; - if (phpdbg_is_class_method(expr, expr_len, &class_name, &func_name)) { - zend_class_entry **ce; - - if (zend_lookup_class(class_name, strlen(class_name), &ce TSRMLS_CC) == SUCCESS) { - zend_function *fbc; - char *lcname = zend_str_tolower_dup(func_name, strlen(func_name)); + if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + zend_function *fbc; + char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); - 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", - fbc->common.function_name); - - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The method %s could not be found", func_name); - } - - efree(lcname); + 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", + fbc->common.function_name); + + phpdbg_print_function_helper(fbc TSRMLS_CC); } else { - phpdbg_error("Failed to find the requested class %s", class_name); + phpdbg_error( + "The method %s could not be found", param->method.name); + result = FAILURE; } - efree(class_name); - efree(func_name); + efree(lcname); } else { - phpdbg_error("The expression provided is not a valid method %s", expr); + phpdbg_error( + "Failed to find the requested class %s", param->method.class); + result = FAILURE; } } else { - phpdbg_error("No expression provided"); + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + result = FAILURE; } - return SUCCESS; + + return result; } /* }}} */ PHPDBG_PRINT(func) /* {{{ */ { - if (expr && expr_len > 0L) { + int result = SUCCESS; + + if (param->type == STR_PARAM) { HashTable *func_table = EG(function_table); zend_function* fbc; - const char *func_name = expr; - size_t func_name_len = expr_len; + const char *func_name = param->str; + size_t func_name_len = param->len; char *lcname; /* search active scope if begins with period */ if (func_name[0] == '.') { @@ -181,11 +186,12 @@ PHPDBG_PRINT(func) /* {{{ */ func_table = &EG(scope)->function_table; } else { phpdbg_error("No active class"); - return SUCCESS; + return FAILURE; } } else if (!EG(function_table)) { - phpdbg_error("No function table loaded"); - return SUCCESS; + phpdbg_error( + "No function table loaded"); + return FAILURE; } else { func_table = EG(function_table); } @@ -201,12 +207,18 @@ PHPDBG_PRINT(func) /* {{{ */ phpdbg_print_function_helper(fbc TSRMLS_CC); } else { - phpdbg_error("Function %s not found", func_name); + phpdbg_error( + "Function %s not found", func_name); + result = FAILURE; } efree(lcname); + } else { - phpdbg_error("No function name provided"); + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + result = FAILURE; } - return SUCCESS; + + return result; } /* }}} */ diff --git a/phpdbg_print.h b/phpdbg_print.h index 68e1f5e769..9cffbe64b5 100644 --- a/phpdbg_print.h +++ b/phpdbg_print.h @@ -29,7 +29,7 @@ #define PHPDBG_PRINT_D(name, tip, alias) \ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_print_##name} #define PHPDBG_PRINT(name) \ - int phpdbg_do_print_##name(const char *expr, size_t expr_len TSRMLS_DC) + int phpdbg_do_print_##name(phpdbg_param_t *param TSRMLS_DC) /** * Printer Forward Declarations diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index aa75fefa48..ec5a7e780f 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -188,30 +188,38 @@ void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ static PHPDBG_COMMAND(exec) /* {{{ */ { - if (expr_len == 0) { + if (param->type == EMPTY_PARAM) { phpdbg_error("No expression provided"); return SUCCESS; + } else { + if (param->type == STR_PARAM) { + if (PHPDBG_G(exec)) { + phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); + efree(PHPDBG_G(exec)); + PHPDBG_G(exec) = NULL; + } + + if (PHPDBG_G(ops)) { + phpdbg_notice("Destroying compiled opcodes"); + phpdbg_clean(0 TSRMLS_CC); + } + + PHPDBG_G(exec) = phpdbg_resolve_path(param->str TSRMLS_CC); + + if (!PHPDBG_G(exec)) { + phpdbg_error("Cannot get real file path"); + return FAILURE; + } + + PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); + + phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + } else { + phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + } } - if (PHPDBG_G(exec)) { - phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); - efree(PHPDBG_G(exec)); - PHPDBG_G(exec) = NULL; - } - if (PHPDBG_G(ops)) { - phpdbg_notice("Destroying compiled opcodes"); - phpdbg_clean(0 TSRMLS_CC); - } - - PHPDBG_G(exec) = phpdbg_resolve_path(expr TSRMLS_CC); - - if (!PHPDBG_G(exec)) { - phpdbg_error("Cannot get real file path"); - return FAILURE; - } - - PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); - - phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + + return SUCCESS; } /* }}} */ @@ -259,15 +267,19 @@ static PHPDBG_COMMAND(compile) /* {{{ */ static PHPDBG_COMMAND(step) /* {{{ */ { - if (expr && atoi(expr)) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + if (param->type == EMPTY_PARAM || param->type == NUMERIC_PARAM) { + if (param->type == NUMERIC_PARAM && param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; + } + + phpdbg_notice("Stepping %s", + (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); } else { - PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; + phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); } - phpdbg_notice("Stepping %s", - (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - return SUCCESS; } /* }}} */ @@ -333,32 +345,38 @@ static PHPDBG_COMMAND(run) /* {{{ */ static PHPDBG_COMMAND(eval) /* {{{ */ { - zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING); - zval retval; - - if (expr_len == 0) { + if (param->type == EMPTY_PARAM) { phpdbg_error("No expression provided!"); return FAILURE; + } else { + if (param->type == STR_PARAM) { + zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING); + zval retval; + + PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; + + /* disable stepping while eval() in progress */ + PHPDBG_G(flags) |= PHPDBG_IN_EVAL; + if (zend_eval_stringl(param->str, param->len, + &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { + zend_print_zval_r( + &retval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + zval_dtor(&retval); + } + PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; + + /* switch stepping back on */ + if (stepping) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } + } else { + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; + } } - - PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; - - /* disable stepping while eval() in progress */ - PHPDBG_G(flags) |= PHPDBG_IN_EVAL; - if (zend_eval_stringl((char*)expr, expr_len, - &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { - zend_print_zval_r( - &retval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); - zval_dtor(&retval); - } - PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; - - /* switch stepping back on */ - if (stepping) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - } - + return SUCCESS; } /* }}} */ @@ -374,7 +392,7 @@ static PHPDBG_COMMAND(back) /* {{{ */ return FAILURE; } - limit = (expr != NULL) ? atoi(expr) : 0; + limit = (param->type == NUMERIC_PARAM) ? param->num : 0; zend_fetch_debug_backtrace(&zbacktrace, 0, 0, limit TSRMLS_CC); @@ -395,9 +413,9 @@ static PHPDBG_COMMAND(back) /* {{{ */ static PHPDBG_COMMAND(print) /* {{{ */ { - if (expr && expr_len > 0L) { - if (phpdbg_do_cmd(phpdbg_print_commands, (char*)expr, expr_len TSRMLS_CC) == FAILURE) { - phpdbg_error("Failed to find print command %s", expr); + if (param->type == STR_PARAM) { + if (phpdbg_do_cmd(phpdbg_print_commands, param->str, param->len TSRMLS_CC) == FAILURE) { + phpdbg_error("Failed to find print command %s", param->str); } return SUCCESS; } @@ -448,40 +466,40 @@ static PHPDBG_COMMAND(print) /* {{{ */ static PHPDBG_COMMAND(break) /* {{{ */ { - phpdbg_param_t param; - - if (expr_len == 0) { + if (param->type == EMPTY_PARAM) { phpdbg_error("No expression found"); return FAILURE; } /* allow advanced breakers to run */ - if (phpdbg_do_cmd(phpdbg_break_commands, (char*)expr, expr_len TSRMLS_CC) == SUCCESS) { + if (param->type == STR_PARAM && + phpdbg_do_cmd(phpdbg_break_commands, param->str, param->len TSRMLS_CC) == SUCCESS) { return SUCCESS; } - switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) { + switch (param->type) { case ADDR_PARAM: - phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC); + phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); break; case NUMERIC_PARAM: - phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param.num TSRMLS_CC); + phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); break; case METHOD_PARAM: - phpdbg_set_breakpoint_method(param.method.class, param.method.name TSRMLS_CC); + phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); break; case FILE_PARAM: - phpdbg_set_breakpoint_file(param.file.name, param.file.line TSRMLS_CC); + phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break; case STR_PARAM: - phpdbg_set_breakpoint_symbol(param.str TSRMLS_CC); + phpdbg_set_breakpoint_symbol(param->str TSRMLS_CC); break; + default: - break; + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } - phpdbg_clear_param(¶m TSRMLS_CC); - return SUCCESS; } /* }}} */ @@ -554,25 +572,25 @@ static PHPDBG_COMMAND(aliases) /* {{{ */ static PHPDBG_COMMAND(oplog) /* {{{ */ { - if (expr && expr_len > 0L) { - /* disable oplog */ - if (expr[0] == '0' && expr_len == 1) { - if (PHPDBG_G(oplog)) { - phpdbg_notice("Disabling oplog"); - fclose( - PHPDBG_G(oplog)); - return SUCCESS; - } else { - phpdbg_error("No oplog currently open"); - return FAILURE; - } + if (param->type == EMPTY_PARAM || + ((param->type == NUMERIC_PARAM) && !param->num)) { + if (PHPDBG_G(oplog)) { + phpdbg_notice("Disabling oplog"); + fclose( + PHPDBG_G(oplog)); + return SUCCESS; } else { + phpdbg_error("No oplog currently open"); + return FAILURE; + } + } else { + if (param->type == STR_PARAM) { /* open oplog */ FILE *old = PHPDBG_G(oplog); - PHPDBG_G(oplog) = fopen(expr, "w+"); + PHPDBG_G(oplog) = fopen(param->str, "w+"); if (!PHPDBG_G(oplog)) { - phpdbg_error("Failed to open %s for oplog", expr); + phpdbg_error("Failed to open %s for oplog", param->str); PHPDBG_G(oplog) = old; return FAILURE; } else { @@ -580,14 +598,15 @@ static PHPDBG_COMMAND(oplog) /* {{{ */ phpdbg_notice("Closing previously open oplog"); fclose(old); } - phpdbg_notice("Successfully opened oplog"); + phpdbg_notice("Successfully opened oplog %s", param->str); return SUCCESS; } + } else { + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } - } else { - phpdbg_error("No expression provided"); - return FAILURE; } } /* }}} */ @@ -596,9 +615,9 @@ static PHPDBG_COMMAND(help) /* {{{ */ phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); - if (expr_len > 0L) { - if (phpdbg_do_cmd(phpdbg_help_commands, (char*)expr, expr_len TSRMLS_CC) == FAILURE) { - phpdbg_error("Failed to find help command: %s", expr); + if (param->type == STR_PARAM) { + if (phpdbg_do_cmd(phpdbg_help_commands, param->str, param->len TSRMLS_CC) == FAILURE) { + phpdbg_error("Failed to find help command: %s", param->str); } } else { const phpdbg_command_t *prompt_command = phpdbg_prompt_commands; @@ -642,36 +661,40 @@ static PHPDBG_COMMAND(help) /* {{{ */ } /* }}} */ static PHPDBG_COMMAND(quiet) { /* {{{ */ - if (expr && atoi(expr)) { - PHPDBG_G(flags) |= PHPDBG_IS_QUIET; + if (param->type == NUMERIC_PARAM) { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_QUIET; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } + phpdbg_notice("Quietness %s", + (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled"); } else { - PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + phpdbg_error( + "Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC)); + return FAILURE; } - - phpdbg_notice("Quietness %s", - (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled"); - + return SUCCESS; } /* }}} */ static PHPDBG_COMMAND(list) /* {{{ */ { - phpdbg_param_t param; - /* allow advanced listers to run */ - if (phpdbg_do_cmd(phpdbg_list_commands, (char*)expr, expr_len TSRMLS_CC) == SUCCESS) { + if (param->type == STR_PARAM && + phpdbg_do_cmd(phpdbg_list_commands, param->str, param->len TSRMLS_CC) == SUCCESS) { return SUCCESS; } - - phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC); - phpdbg_list_dispatch(¶m TSRMLS_CC); - phpdbg_clear_param(¶m TSRMLS_CC); + + phpdbg_list_dispatch(param TSRMLS_CC); return SUCCESS; } /* }}} */ int phpdbg_do_cmd(const phpdbg_command_t *command, 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); @@ -684,21 +707,33 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0) || ((expr_len == 1) && (command->alias && command->alias == cmd_line[0]))) { + + phpdbg_param_t *param = emalloc(sizeof(phpdbg_param_t)); + PHPDBG_G(last) = (phpdbg_command_t*) command; - PHPDBG_G(last_params) = expr; - PHPDBG_G(last_params_len) = (cmd_len - expr_len) ? - (((cmd_len - expr_len) - sizeof(" "))+1) : 0; - - phpdbg_debug("phpdbg_do_cmd(%s, \"%s\", %lu)", - command->name, PHPDBG_G(last_params), PHPDBG_G(last_params_len)); - - return command->handler( - PHPDBG_G(last_params), PHPDBG_G(last_params_len) TSRMLS_CC); + 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; + + phpdbg_debug("phpdbg_do_cmd(%s, \"%s\")", + command->name, phpdbg_get_param_type(param TSRMLS_CC)); + + rc = command->handler(param TSRMLS_CC); + break; } ++command; } - return FAILURE; + return rc; } /* }}} */ int phpdbg_interactive(TSRMLS_D) /* {{{ */ @@ -756,9 +791,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } #endif } else if (PHPDBG_G(last)) { - ret = PHPDBG_G(last)->handler( - PHPDBG_G(last_params), PHPDBG_G(last_params_len) TSRMLS_CC); - + ret = PHPDBG_G(last)->handler(PHPDBG_G(lparam) TSRMLS_CC); goto out; } } diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 2eae44c786..7fe6d0dbe8 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -43,7 +43,7 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le #define PHPDBG_COMMAND_EX_D(name, tip, alias) \ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name} #define PHPDBG_COMMAND(name) \ - int phpdbg_do_##name(const char *expr, size_t expr_len TSRMLS_DC) + 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);