From: Felipe Pena Date: Wed, 13 Nov 2013 23:13:41 +0000 (-0200) Subject: - Added parameter parsing functions X-Git-Tag: php-5.6.0alpha1~110^2~352 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4c59ad6e2e542be1c6edd8a8ee398ed8c5d72d32;p=php - Added parameter parsing functions --- diff --git a/phpdbg_break.c b/phpdbg_break.c index b2461dc2ae..8b114abf7e 100644 --- a/phpdbg_break.c +++ b/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, ¶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; } /* }}} */ @@ -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, ¶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; } /* }}} */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 0b9f516518..1596ca5e62 100644 --- a/phpdbg_prompt.c +++ b/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, ¶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; } /* }}} */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index d506a25eed..8c48390143 100644 --- a/phpdbg_utils.c +++ b/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; } /* }}} */ diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 615e33506b..82e7ef6c86 100644 --- a/phpdbg_utils.h +++ b/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 */