PHPDBG_BREAK(file) /* {{{ */
{
- const char *line_pos;
-
- if (!expr || expr_len == 0) {
- phpdbg_error("No expression provided");
- return SUCCESS;
- }
-
- line_pos = strchr(expr, ':');
-
- if (!line_pos) {
- phpdbg_error("No line specified in expression %s", expr);
- return SUCCESS;
+ phpdbg_param_t param;
+
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
+ case EMPTY_PARAM:
+ phpdbg_error("No expression provided");
+ break;
+ case FILE_PARAM:
+ phpdbg_set_breakpoint_file(param.file.name, param.file.line TSRMLS_CC);
+ break;
+ default:
+ phpdbg_error("Wrong parameter");
+ break;
}
- if (phpdbg_is_class_method(expr, expr_len, NULL, NULL)) {
- phpdbg_error("Expected file:line format");
- return SUCCESS;
- } else {
- char path[MAXPATHLEN], resolved_name[MAXPATHLEN];
- long line_num = strtol(line_pos+1, NULL, 0);
-
- memcpy(path, expr, line_pos - expr);
- path[line_pos - expr] = 0;
+ phpdbg_clear_param(¶m);
- if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
- phpdbg_error("Failed to expand path %s", path);
- return SUCCESS;
- }
-
- phpdbg_set_breakpoint_file(resolved_name, line_num TSRMLS_CC);
- }
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(method) /* {{{ */
{
- char *class_name;
- char *func_name;
-
- if (expr && expr_len >0L) {
- if (phpdbg_is_class_method(expr, expr_len+1, &class_name, &func_name)) {
- phpdbg_set_breakpoint_method(
- class_name, func_name TSRMLS_CC);
- } else {
- phpdbg_error(
- "The expression provided is not a method name: %s", expr);
- }
- } else {
- phpdbg_error("No expression provided");
+ phpdbg_param_t param;
+
+ 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");
+ break;
}
+ phpdbg_clear_param(¶m);
+
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(address) /* {{{ */
{
- if (expr && expr_len > 0L) {
- if (phpdbg_is_addr(expr)) {
- phpdbg_set_breakpoint_opline(
- strtoul(expr, 0, 16) TSRMLS_CC);
- } else {
- phpdbg_error("The expression provided is not an address: %s", expr);
- }
- } else {
- phpdbg_error("No expression provided");
+ phpdbg_param_t param;
+
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
+ case EMPTY_PARAM:
+ phpdbg_error("No expression provided");
+ break;
+ case ADDR_PARAM:
+ phpdbg_set_breakpoint_opline(param.addr TSRMLS_CC);
+ break;
+ default:
+ phpdbg_error("Wrong parameter");
+ break;
}
+
+ phpdbg_clear_param(¶m);
+
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(lineno) /* {{{ */
{
+ phpdbg_param_t param;
+
if (!PHPDBG_G(exec)) {
phpdbg_error("Not file context found!");
return SUCCESS;
}
- if (expr_len == 0) {
- phpdbg_error("No expression provided!");
- return SUCCESS;
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
+ 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);
+ break;
+ default:
+ phpdbg_error("Wrong parameter");
+ break;
}
- if (phpdbg_is_numeric(expr)) {
- const char *filename = zend_get_executed_filename(TSRMLS_C);
-
- if (filename &&
- !memcmp(filename, "[no active file]", sizeof("[no active file]"))) {
- phpdbg_set_breakpoint_file(filename, strtol(expr, NULL, 0) TSRMLS_CC);
- } else {
- phpdbg_error("No file context found");
- }
- } else {
- phpdbg_error(
- "The expression provided is not a valid line number %s", expr);
- }
+ phpdbg_clear_param(¶m);
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(func) /* {{{ */
{
- char name[200];
- size_t name_len = expr_len;
-
- if (expr_len == 0) {
- phpdbg_error("No expression provided");
- return SUCCESS;
- }
-
- if (expr_len >= 200) {
- phpdbg_error("Name is too long");
- return SUCCESS;
+ phpdbg_param_t param;
+
+ switch (phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC)) {
+ case EMPTY_PARAM:
+ phpdbg_error("No expression provided!");
+ break;
+ case STR_PARAM:
+ phpdbg_set_breakpoint_symbol(param.str TSRMLS_CC);
+ break;
+ default:
+ phpdbg_error("Wrong parameter");
+ break;
}
- memcpy(name, expr, name_len);
- name[name_len] = 0;
-
- phpdbg_set_breakpoint_symbol(name TSRMLS_CC);
+ phpdbg_clear_param(¶m);
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(break) /* {{{ */
{
+ phpdbg_param_t param;
char *line_pos;
if (expr_len == 0) {
return SUCCESS;
}
- line_pos = strchr(expr, ':');
-
- if (line_pos) {
- char *class;
- char *func;
-
- /* break class::method */
- if (phpdbg_is_class_method(expr, expr_len, &class, &func)) {
- phpdbg_set_breakpoint_method(class, func TSRMLS_CC);
- } else {
- /* break file:line */
- char path[MAXPATHLEN], resolved_name[MAXPATHLEN];
- long line_num = strtol(line_pos+1, NULL, 0);
-
- if (line_num) {
- memcpy(path, expr, line_pos - expr);
- path[line_pos - expr] = 0;
-
- if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
- phpdbg_error("Failed to expand path %s", path);
- return FAILURE;
- }
-
- phpdbg_set_breakpoint_file(resolved_name, line_num TSRMLS_CC);
- } else {
- phpdbg_error("No line specified in expression %s", expr);
- return FAILURE;
- }
- }
- } else {
- /* break 0xc0ffee */
- if (phpdbg_is_addr(expr)) {
- zend_ulong opline = strtoul(expr, 0, 16);
-
- phpdbg_set_breakpoint_opline(opline TSRMLS_CC);
- } else if (phpdbg_is_numeric(expr)) {
- /* break 1337 */
- const char *filename = zend_get_executed_filename(TSRMLS_C);
- long line_num = strtol(expr, NULL, 0);
-
- if (!filename) {
- phpdbg_error("No file context found");
- return FAILURE;
- }
-
- phpdbg_set_breakpoint_file(filename, line_num TSRMLS_CC);
- } else {
- /* break symbol */
- char name[200];
- size_t name_len = strlen(expr);
-
- if (name_len) {
- name_len = MIN(name_len, 200);
- memcpy(name, expr, name_len);
- name[name_len] = 0;
-
- phpdbg_set_breakpoint_symbol(name TSRMLS_CC);
- } else {
- phpdbg_error("Malformed break command found");
- return FAILURE;
- }
- }
+ switch (phpdbg_parse_param(expr, expr_len, ¶m)) {
+ case ADDR_PARAM:
+ 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);
+ break;
+ case METHOD_PARAM:
+ 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);
+ case STR_PARAM:
+ phpdbg_set_breakpoint_symbol(param.str TSRMLS_CC);
+ break;
+ default:
+ break;
}
+ phpdbg_clear_param(¶m);
return SUCCESS;
} /* }}} */
*class = estrndup(str, sep - str);
(*class)[sep - str] = 0;
}
-
+
if (method != NULL) {
*method = estrndup(
sep+2, str + len - (sep + 2));
return 1;
} /* }}} */
+const char *phpdbg_current_file(TSRMLS_D)
+{
+ const char *file = PHPDBG_G(exec);
+
+ if (!file) {
+ file = zend_get_executed_filename(TSRMLS_C);
+ }
+ 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], resolved_name[MAXPATHLEN];
+
+ memcpy(path, str, line_pos - str);
+ path[line_pos - str] = 0;
+
+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
+ goto out;
+ }
+
+ param->file.name = estrndup(resolved_name, line_pos - str);
+ param->file.line = strtol(line_pos+1, NULL, 0);
+ return FILE_PARAM;
+ }
+ }
+out:
+ param->str = estrndup(str, len);
+ return STR_PARAM;
+} /* }}} */
+
+void phpdbg_clear_param(int type, phpdbg_param_t *param) /* {{{ */
+{
+ 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, const char *format, ...) /* {{{ */
{
int rc = 0;
buffer,
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "]\033[0m" : "]"));
break;
-
+
case P_WRITELN: {
if (buffer) {
rc = printf("%s%s%s\n",
rc = printf("\n");
}
} break;
-
+
case P_WRITE: if (buffer) {
rc = printf("%s%s%s",
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[37m" : ""),
if (buffer) {
efree(buffer);
}
-
+
return rc;
} /* }}} */
int phpdbg_is_addr(const char*);
int phpdbg_is_class_method(const char*, size_t, char**, char**);
+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;
+
+const char *phpdbg_current_file(TSRMLS_D);
+
/**
* Error/notice/formatting helper
*/