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;
FILE *oplog; /* opline log */
ZEND_END_MODULE_GLOBALS(phpdbg)
+/* {{{ 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)(const char* expr, size_t expr_len 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 */
+};
+
+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 */
PHPDBG_BREAK(file) /* {{{ */
{
phpdbg_param_t param;
- int type;
-
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
phpdbg_set_breakpoint_file(param.file.name, param.file.line TSRMLS_CC);
break;
default:
- phpdbg_error("Wrong parameter");
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(method) /* {{{ */
{
phpdbg_param_t param;
- int type;
-
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
case METHOD_PARAM:
phpdbg_set_breakpoint_method(param.method.class, param.method.name TSRMLS_CC);
break;
+
default:
- phpdbg_error("Wrong parameter");
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(address) /* {{{ */
{
phpdbg_param_t param;
- int type;
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC);
break;
default:
- phpdbg_error("Wrong parameter");
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(lineno) /* {{{ */
{
phpdbg_param_t param;
- int type;
-
+
if (!PHPDBG_G(exec)) {
phpdbg_error("Not file context found!");
return SUCCESS;
}
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case EMPTY_PARAM:
phpdbg_error("No expression provided!");
break;
phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param.num TSRMLS_CC);
break;
default:
- phpdbg_error("Wrong parameter");
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(func) /* {{{ */
{
phpdbg_param_t param;
- int type;
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case EMPTY_PARAM:
phpdbg_error("No expression provided!");
break;
phpdbg_set_breakpoint_symbol(param.str TSRMLS_CC);
break;
default:
- phpdbg_error("Wrong parameter");
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
PHPDBG_LIST(lines) /* {{{ */
{
phpdbg_param_t param;
- int type = phpdbg_parse_param(
- expr, expr_len, ¶m TSRMLS_CC);
- switch (type) {
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case NUMERIC_PARAM:
case EMPTY_PARAM: {
if (PHPDBG_G(exec) || zend_is_executing(TSRMLS_C)) {
- if (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_error("Not executing, and execution context not set");
} break;
default:
- phpdbg_error("Unsupported parameter type (%d) for command", type);
+ phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶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) {
+
+ if (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC) == STR_PARAM) {
i_phpdbg_list_func(
param.str TSRMLS_CC);
+ } else {
+ phpdbg_error(
+ "Unsupported parameter type (%s) for function", phpdbg_get_param_type(¶m TSRMLS_CC));
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
-void phpdbg_list_dispatch(int type, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
+void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC) /* {{{ */
{
- switch (type) {
+ switch (param->type) {
case NUMERIC_PARAM:
case EMPTY_PARAM: {
if (PHPDBG_G(exec) || zend_is_executing(TSRMLS_C)) {
- if (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_error("Not executing, and execution context not set");
} break;
default:
- phpdbg_error("Unsupported input type (%d) for command", type);
+ phpdbg_error(
+ "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
break;
}
} /* }}} */
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);
+void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC);
static const phpdbg_command_t phpdbg_list_commands[] = {
PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'),
static PHPDBG_COMMAND(break) /* {{{ */
{
phpdbg_param_t param;
- int type;
if (expr_len == 0) {
phpdbg_error("No expression found");
return SUCCESS;
}
- switch ((type=phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC))) {
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
case ADDR_PARAM:
phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC);
break;
break;
}
- phpdbg_clear_param(type, ¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(list) /* {{{ */
{
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);
+
+ phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC);
+ phpdbg_list_dispatch(¶m TSRMLS_CC);
+ phpdbg_clear_param(¶m TSRMLS_CC);
return SUCCESS;
} /* }}} */
#define PHPDBG_NEXT 2
#define PHPDBG_UNTIL 3
-/**
- * Command handler
- */
-typedef int (*phpdbg_command_handler_t)(const char* expr, size_t expr_len TSRMLS_DC);
-
-/**
- * Command representation
- */
-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 */
-} ;
-
/**
* Command Executor
*/
return file;
} /* }}} */
-int phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
-{
- char *class_name, *func_name;
-
- if (len == 0) {
- return EMPTY_PARAM;
- }
-
- if (phpdbg_is_addr(str)) {
- param->addr = strtoul(str, 0, 16);
- return ADDR_PARAM;
- } else if (phpdbg_is_numeric(str)) {
- param->num = strtol(str, NULL, 0);
- return NUMERIC_PARAM;
- } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) {
- param->method.class = class_name;
- param->method.name = func_name;
- return METHOD_PARAM;
- } 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);
- return FILE_PARAM;
- }
- }
-
- param->str = estrndup(str, len);
- return STR_PARAM;
-} /* }}} */
-
-void phpdbg_clear_param(int type, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
-{
- switch (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_print(int type TSRMLS_DC, FILE *fp, const char *format, ...) /* {{{ */
{
int rc = 0;
int phpdbg_is_empty(const char*);
int phpdbg_is_addr(const char*);
int phpdbg_is_class_method(const char*, size_t, char**, char**);
-
-/**
- * Parameter parsing stuff
- */
-enum {
- EMPTY_PARAM = 0,
- ADDR_PARAM,
- FILE_PARAM,
- METHOD_PARAM,
- STR_PARAM,
- NUMERIC_PARAM
-};
-
-typedef union _phpdbg_param {
- long num;
- zend_ulong addr;
- struct {
- char *name;
- long line;
- } file;
- struct {
- char *class;
- char *name;
- } method;
- char *str;
-} 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);