Browse Source

- Added parameter parsing functions

pull/550/head
Felipe Pena 13 years ago
parent
commit
4c59ad6e2e
  1. 149
      phpdbg_break.c
  2. 81
      phpdbg_prompt.c
  3. 77
      phpdbg_utils.c
  4. 25
      phpdbg_utils.h

149
phpdbg_break.c

@ -28,72 +28,64 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
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, &param 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(&param);
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, &param 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(&param);
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, &param 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(&param);
return SUCCESS;
} /* }}} */
@ -112,52 +104,47 @@ PHPDBG_BREAK(on) /* {{{ */
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, &param 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(&param);
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, &param 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(&param);
return SUCCESS;
} /* }}} */

81
phpdbg_prompt.c

@ -316,6 +316,7 @@ static PHPDBG_COMMAND(print) /* {{{ */
static PHPDBG_COMMAND(break) /* {{{ */
{
phpdbg_param_t param;
char *line_pos;
if (expr_len == 0) {
@ -328,69 +329,25 @@ static PHPDBG_COMMAND(break) /* {{{ */
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, &param)) {
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(&param);
return SUCCESS;
} /* }}} */

77
phpdbg_utils.c

@ -67,7 +67,7 @@ int phpdbg_is_class_method(const char *str, size_t len, char **class, char **met
*class = estrndup(str, sep - str);
(*class)[sep - str] = 0;
}
if (method != NULL) {
*method = estrndup(
sep+2, str + len - (sep + 2));
@ -76,6 +76,75 @@ int phpdbg_is_class_method(const char *str, size_t len, char **class, char **met
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;
@ -104,7 +173,7 @@ int phpdbg_print(int type TSRMLS_DC, const char *format, ...) /* {{{ */
buffer,
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "]\033[0m" : "]"));
break;
case P_WRITELN: {
if (buffer) {
rc = printf("%s%s%s\n",
@ -115,7 +184,7 @@ int phpdbg_print(int type TSRMLS_DC, const char *format, ...) /* {{{ */
rc = printf("\n");
}
} break;
case P_WRITE: if (buffer) {
rc = printf("%s%s%s",
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[37m" : ""),
@ -127,6 +196,6 @@ int phpdbg_print(int type TSRMLS_DC, const char *format, ...) /* {{{ */
if (buffer) {
efree(buffer);
}
return rc;
} /* }}} */

25
phpdbg_utils.h

@ -28,6 +28,31 @@ int phpdbg_is_empty(const char*);
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
*/

Loading…
Cancel
Save