diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2014-10-28 17:40:27 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2014-10-28 17:40:27 +0100 |
commit | ec533514473d480b2619ee0f81e49f8a7683bdf2 (patch) | |
tree | 0b359cd91f3c5a8a2f8280686558f404b2dc2075 | |
parent | efe9cc3a86a769f1ac3d16f4b12f5e83053c6822 (diff) | |
parent | 297baa0c18d8d04de7a683a51b9f069c84a855f3 (diff) | |
download | php-git-ec533514473d480b2619ee0f81e49f8a7683bdf2.tar.gz |
Merge remote-tracking branch 'origin/PHP-5.6'
Conflicts:
configure.in
main/php_version.h
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg_bp.c
sapi/phpdbg/phpdbg_prompt.c
-rw-r--r-- | sapi/phpdbg/phpdbg.c | 83 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_bp.c | 117 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_bp.h | 3 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_io.c | 4 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_out.c | 16 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 190 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_prompt.h | 1 |
7 files changed, 234 insertions, 180 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 43881a370f..6e7e4ece34 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1013,20 +1013,12 @@ int main(int argc, char **argv) /* {{{ */ zend_bool remote = 0; int step = 0; zend_phpdbg_globals *settings = NULL; - -#ifdef _WIN32 - char *bp_tmp_file = NULL; -#else - char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX"; -#endif - -#ifndef _WIN32 + char *bp_tmp = NULL; char *address; int listen = -1; int server = -1; int socket = -1; FILE* stream = NULL; -#endif #ifdef ZTS void ***tsrm_ls; @@ -1058,29 +1050,6 @@ int main(int argc, char **argv) /* {{{ */ #endif phpdbg_main: - if (!cleaning) { - -#ifdef _WIN32 - bp_tmp_file = malloc(L_tmpnam); - - if (bp_tmp_file) { - if (!tmpnam(bp_tmp_file)) { - free(bp_tmp_file); - bp_tmp_file = NULL; - } - } - - if (!bp_tmp_file) { - phpdbg_error("tmpfile", "", "Unable to create temporary file"); - return 1; - } -#else - if (!mkstemp(bp_tmp_file)) { - memset(bp_tmp_file, 0, sizeof(bp_tmp_file)); - } -#endif - - } ini_entries = NULL; ini_entries_len = 0; ini_ignore = 0; @@ -1455,7 +1424,7 @@ phpdbg_main: if (exec) { /* set execution context */ PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC); - PHPDBG_G(exec_len) = strlen(exec); + PHPDBG_G(exec_len) = PHPDBG_G(exec) ? strlen(PHPDBG_G(exec)) : 0; free(exec); exec = NULL; @@ -1491,9 +1460,13 @@ phpdbg_main: PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC); - PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; - phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC); - PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; + if (bp_tmp) { + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; + phpdbg_string_init(bp_tmp TSRMLS_CC); + free(bp_tmp); + bp_tmp = NULL; + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; + } } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; @@ -1516,32 +1489,36 @@ phpdbg_main: PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } - if (phpdbg_startup_run) { - zend_try { - PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); - } zend_end_try(); - if (phpdbg_startup_run > 1) { - /* if -r is on the command line more than once just quit */ - goto phpdbg_out; - } - phpdbg_startup_run = 0; - } - /* #ifndef for making compiler shutting up */ #ifndef _WIN32 phpdbg_interact: #endif + /* phpdbg main() */ do { zend_try { + if (phpdbg_startup_run) { + zend_bool quit_immediately = phpdbg_startup_run > 1; + phpdbg_startup_run = 0; + PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); + if (quit_immediately) { + /* if -r is on the command line more than once just quit */ + EG(bailout) = __orig_bailout; /* reset zend_try */ + break; + } + } + phpdbg_interactive(1 TSRMLS_CC); } zend_catch { if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) { - FILE *bp_tmp_fp = fopen(bp_tmp_file, "w"); + char *bp_tmp_str; PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; - phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC); + phpdbg_export_breakpoints_to_string(&bp_tmp_str TSRMLS_CC); PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; - fclose(bp_tmp_fp); + if (bp_tmp_str) { + bp_tmp = strdup(bp_tmp_str); + efree(bp_tmp_str); + } cleaning = 1; } else { cleaning = 0; @@ -1686,11 +1663,5 @@ phpdbg_out: free(PHPDBG_G(sapi_name_ptr)); } -#ifdef _WIN32 - free(bp_tmp_file); -#else - unlink(bp_tmp_file); -#endif - return 0; } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index 440240483f..311171f72c 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -104,9 +104,18 @@ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ { + char *string; + phpdbg_export_breakpoints_to_string(&string TSRMLS_CC); + fputs(string, handle); +} + +PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC) /* {{{ */ +{ HashTable *table; zend_ulong id = 0L; + *str = ""; + if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); @@ -116,52 +125,54 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ ZEND_HASH_FOREACH_PTR(table, brake) { if (brake->id == id) { + char *new_str = NULL; + switch (brake->type) { case PHPDBG_BREAK_FILE: { - fprintf(handle, - "break %s:%lu\n", + phpdbg_asprintf(&new_str, + "%sbreak %s:%lu\n", *str, ((phpdbg_breakfile_t*)brake)->filename, ((phpdbg_breakfile_t*)brake)->line); } break; case PHPDBG_BREAK_SYM: { - fprintf(handle, - "break %s\n", + phpdbg_asprintf(&new_str, + "%sbreak %s\n", *str, ((phpdbg_breaksymbol_t*)brake)->symbol); } break; case PHPDBG_BREAK_METHOD: { - fprintf(handle, - "break %s::%s\n", + phpdbg_asprintf(&new_str, + "%sbreak %s::%s\n", *str, ((phpdbg_breakmethod_t*)brake)->class_name, ((phpdbg_breakmethod_t*)brake)->func_name); } break; case PHPDBG_BREAK_METHOD_OPLINE: { - fprintf(handle, - "break %s::%s#%llu\n", + phpdbg_asprintf(&new_str, + "%sbreak %s::%s#%llu\n", *str, ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_FUNCTION_OPLINE: { - fprintf(handle, - "break %s#%llu\n", + phpdbg_asprintf(&new_str, + "%sbreak %s#%llu\n", *str, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_FILE_OPLINE: { - fprintf(handle, - "break %s:#%llu\n", + phpdbg_asprintf(&new_str, + "%sbreak %s:#%llu\n", *str, ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_OPCODE: { - fprintf(handle, - "break %s\n", + phpdbg_asprintf(&new_str, + "%sbreak %s\n", *str, ((phpdbg_breakop_t*)brake)->name); } break; @@ -171,20 +182,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ if (conditional->paramed) { switch (conditional->param.type) { case STR_PARAM: - fprintf(handle, - "break at %s if %s\n", conditional->param.str, conditional->code); + phpdbg_asprintf(&new_str, + "%sbreak at %s if %s\n", *str, conditional->param.str, conditional->code); break; case METHOD_PARAM: - fprintf(handle, - "break at %s::%s if %s\n", + phpdbg_asprintf(&new_str, + "%sbreak at %s::%s if %s\n", *str, conditional->param.method.class, conditional->param.method.name, conditional->code); break; case FILE_PARAM: - fprintf(handle, - "break at %s:%lu if %s\n", + phpdbg_asprintf(&new_str, + "%sbreak at %s:%lu if %s\n", *str, conditional->param.file.name, conditional->param.file.line, conditional->code); break; @@ -192,15 +203,23 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ default: { /* do nothing */ } break; } } else { - fprintf( - handle, "break if %s\n", conditional->code); + phpdbg_asprintf(&new_str, "%sbreak if %s\n", str, conditional->code); } } break; } + + if ((*str)[0]) { + efree(*str); + } + *str = new_str; } } ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END(); } + + if (!(*str)[0]) { + *str = NULL; + } } /* }}} */ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */ @@ -219,6 +238,8 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML } path_len = strlen(path); + phpdbg_debug("file path: %s, resolved path: %s, was compiled: %d\n", original_path, path, zend_hash_exists(&PHPDBG_G(file_sources), path, path_len)); + if (!zend_hash_str_exists(&PHPDBG_G(file_sources), path, path_len)) { if (php_stream_stat_path(path, &ssb) == FAILURE) { if (original_path[0] == '/') { @@ -233,6 +254,8 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML } else if (!(ssb.sb.st_mode & (S_IFREG|S_IFLNK))) { phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); return; + } else { + phpdbg_debug("File exists, but not compiled\n"); } } @@ -255,7 +278,11 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML if (pending) { zend_string *file, *path_str = zend_string_init(path, path_len, 0); ZEND_HASH_FOREACH_STR_KEY(&PHPDBG_G(file_sources), file) { - if (!(pending = ((broken = phpdbg_resolve_pending_file_break_ex(file->val, file->len, path_str, broken TSRMLS_CC)) == NULL))) { + HashTable *fileht; + + phpdbg_debug("Compare against loaded %s\n", file); + + if (!(pending = ((fileht = phpdbg_resolve_pending_file_break_ex(file->val, file->len, path_str, broken TSRMLS_CC)) == NULL))) { new_break = *(phpdbg_breakfile_t *) zend_hash_index_find_ptr(broken, line_num); break; } @@ -279,17 +306,18 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uint filelen, zend_string *cur, HashTable *fileht TSRMLS_DC) /* {{{ */ { - if (cur->len < filelen && file[filelen - cur->len - 1] == '/' && !memcmp(file + filelen - cur->len, cur->val, cur->len)) { + phpdbg_debug("file: %s, filelen: %u, cur: %s, curlen %u, pos: %c, memcmp: %d\n", file, filelen, cur, curlen, filelen > curlen ? file[filelen - curlen - 1] : '?', filelen > curlen ? memcmp(file + filelen - curlen, cur, curlen) : 0); + + if (((cur->len < filelen && file[filelen - cur->len - 1] == '/') || filelen == cur->len) && !memcmp(file + filelen - cur->len, cur->val, cur->len)) { phpdbg_breakfile_t *brake, new_brake; - HashTable *master = NULL; - dtor_func_t dtor; + HashTable *master; PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; if (!(master = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen))) { - dtor = PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor; - PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = NULL; - fileht = zend_hash_str_add_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, fileht, sizeof(HashTable)); + HashTable new_ht; + zend_hash_init(&new_ht, 8, NULL, phpdbg_file_breaks_dtor, 0); + master = zend_hash_str_add_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, &new_ht, sizeof(HashTable)); } ZEND_HASH_FOREACH_PTR(fileht, brake) { @@ -300,24 +328,18 @@ PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uin if (master) { zend_hash_index_update_mem(master, brake->line, &new_brake, sizeof(phpdbg_breakfile_t)); PHPDBG_BREAK_MAPPING(brake->id, master); - } else { - efree((char *) brake->filename); - *brake = new_brake; - PHPDBG_BREAK_MAPPING(brake->id, fileht); } } ZEND_HASH_FOREACH_END(); zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur); - if (!master) { - PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = dtor; - } - if (!zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING])) { PHPDBG_G(flags) &= ~PHPDBG_HAS_PENDING_FILE_BP; } - return fileht; + phpdbg_debug("compiled file: %s, cur bp file: %s\n", file, cur); + + return master; } return NULL; @@ -329,7 +351,11 @@ PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC) /* uint filelen = strlen(file); zend_string *cur; + phpdbg_debug("was compiled: %s\n", file); + ZEND_HASH_FOREACH_STR_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur, fileht) { + phpdbg_debug("check bp: %s\n", cur); + phpdbg_resolve_pending_file_break_ex(file, filelen, cur, fileht TSRMLS_CC); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -815,8 +841,21 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_ { HashTable *breaks; phpdbg_breakbase_t *brake; + size_t path_len; + char realpath[MAXPATHLEN]; + const char *path = op_array->filename->val; + + if (VCWD_REALPATH(path, realpath)) { + path = realpath; + } + + path_len = strlen(path); + +#if 0 + phpdbg_debug("Op at: %.*s %d\n", path_len, path, (*EG(opline_ptr))->lineno); +#endif - if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) { + if (!(breaks = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) { return NULL; } diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h index 83c8bbcada..99c4eb6011 100644 --- a/sapi/phpdbg/phpdbg_bp.h +++ b/sapi/phpdbg/phpdbg_bp.h @@ -157,6 +157,7 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC); PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC); /* }}} */ /* {{{ Breakpoint Exportation API */ -PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */ +PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); +PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str TSRMLS_DC); /* }}} */ #endif /* PHPDBG_BP_H */ diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c index 6908a687d7..a2a5c5969f 100644 --- a/sapi/phpdbg/phpdbg_io.c +++ b/sapi/phpdbg/phpdbg_io.c @@ -187,10 +187,6 @@ PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) { - if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { - return 0; - } - if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { return phpdbg_send_bytes(sock, ptr, len); } diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c index 302c075f78..a9edd19ad9 100644 --- a/sapi/phpdbg/phpdbg_out.c +++ b/sapi/phpdbg/phpdbg_out.c @@ -1169,6 +1169,10 @@ PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const va_list args; int errbuf_active = PHPDBG_G(err_buf).active; + if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { + return 0; + } + PHPDBG_G(err_buf).active = 0; #ifdef ZTS @@ -1189,6 +1193,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const c va_list args; int len; + if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { + return 0; + } + va_start(args, strfmt); len = phpdbg_vprint(type TSRMLS_CC, fd, tag, xmlfmt, strfmt, args); va_end(args); @@ -1199,6 +1207,10 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, int fd, const char *tag, const c PHPDBG_API int phpdbg_xml_internal(int fd TSRMLS_DC, const char *fmt, ...) { int len = 0; + if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { + return 0; + } + if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) { va_list args; char *buffer; @@ -1244,6 +1256,10 @@ PHPDBG_API int phpdbg_out_internal(int fd TSRMLS_DC, const char *fmt, ...) { int buflen; int len = 0; + if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { + return 0; + } + va_start(args, fmt); buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args TSRMLS_CC); va_end(args); diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 16807c6402..60c9a2e0a0 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -201,98 +201,128 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * return FAILURE; } /* }}} */ -void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ -{ - struct stat sb; +struct phpdbg_init_state { + int line; + zend_bool in_code; + char *code; + size_t code_len; + const char *init_file; +}; - if (init_file && VCWD_STAT(init_file, &sb) != -1) { - FILE *fp = fopen(init_file, "r"); - if (fp) { - int line = 1; +static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state TSRMLS_DC) { + size_t cmd_len = strlen(cmd); - char cmd[PHPDBG_MAX_CMD]; - size_t cmd_len = 0L; - char *code = NULL; - size_t code_len = 0L; - zend_bool in_code = 0; + state->line++; - while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) { - cmd_len = strlen(cmd)-1; - - while (cmd_len > 0L && isspace(cmd[cmd_len-1])) - cmd_len--; - - cmd[cmd_len] = '\0'; - - if (*cmd && cmd_len > 0L && cmd[0] != '#') { - if (cmd_len == 2) { - if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) { - in_code = 1; - goto next_line; - } else { - if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) { - in_code = 0; - code[code_len] = '\0'; - { - zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC); - } - free(code); - code = NULL; - goto next_line; - } - } - } + while (cmd_len > 0L && isspace(cmd[cmd_len-1])) { + cmd_len--; + } - if (in_code) { - if (code == NULL) { - code = malloc(cmd_len + 1); - } else code = realloc(code, code_len + cmd_len + 1); + cmd[cmd_len] = '\0'; - if (code) { - memcpy( - &code[code_len], cmd, cmd_len); - code_len += cmd_len; - } - goto next_line; - } + if (*cmd && cmd_len > 0L && cmd[0] != '#') { + if (cmd_len == 2) { + if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) { + state->in_code = 1; + return; + } else { + if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) { + state->in_code = 0; + state->code[state->code_len] = '\0'; + zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code" TSRMLS_CC); + free(state->code); + state->code = NULL; + return; + } + } + } - zend_try { - char *input = phpdbg_read_input(cmd TSRMLS_CC); - phpdbg_param_t stack; + if (state->in_code) { + if (state->code == NULL) { + state->code = malloc(cmd_len + 1); + } else { + state->code = realloc(state->code, state->code_len + cmd_len + 1); + } - phpdbg_init_param(&stack, STACK_PARAM); + if (state->code) { + memcpy(&state->code[state->code_len], cmd, cmd_len); + state->code_len += cmd_len; + } - phpdbg_activate_err_buf(1 TSRMLS_CC); + return; + } - if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) { - case FAILURE: - phpdbg_activate_err_buf(0 TSRMLS_CC); - if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input); - } - break; - } - } + zend_try { + char *input = phpdbg_read_input(cmd TSRMLS_CC); + phpdbg_param_t stack; + + phpdbg_init_param(&stack, STACK_PARAM); + + phpdbg_activate_err_buf(1 TSRMLS_CC); + if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { + switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) { + case FAILURE: phpdbg_activate_err_buf(0 TSRMLS_CC); - phpdbg_free_err_buf(TSRMLS_C); - - phpdbg_stack_free(&stack); - phpdbg_destroy_input(&input TSRMLS_CC); - } zend_catch { - PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING); - if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { - zend_bailout(); + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + if (state->init_file) { + phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, state->init_file, state->line, input); + } else { + phpdbg_output_err_buf("initfailure", "%b line=\"%d\" input=\"%s\"", "Unrecognized command on line %d: %s, %b!" TSRMLS_CC, state->line, input); + } } - } zend_end_try(); + break; } -next_line: - line++; } - if (code) { - free(code); + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); + + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); + } zend_catch { + PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING); + if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + zend_bailout(); + } + } zend_end_try(); + } + +} + +void phpdbg_string_init(char *buffer TSRMLS_DC) { + struct phpdbg_init_state state = {0}; + char *str = strtok(buffer, "\n"); + + while (str) { + phpdbg_line_init(str, &state TSRMLS_CC); + + str = strtok(NULL, "\n"); + } + + if (state.code) { + free(state.code); + } +} + +void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ +{ + struct stat sb; + + if (init_file && VCWD_STAT(init_file, &sb) != -1) { + FILE *fp = fopen(init_file, "r"); + if (fp) { + char cmd[PHPDBG_MAX_CMD]; + struct phpdbg_init_state state = {0}; + + state.init_file = init_file; + + while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) { + phpdbg_line_init(cmd, &state TSRMLS_CC); + } + + if (state.code) { + free(state.code); } fclose(fp); @@ -634,10 +664,10 @@ PHPDBG_COMMAND(run) /* {{{ */ if (EG(exception)) { phpdbg_handle_exception(TSRMLS_C); } - - phpdbg_clean(1 TSRMLS_CC); } + phpdbg_clean(1 TSRMLS_CC); + PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING; } else { phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!"); @@ -1081,7 +1111,7 @@ PHPDBG_COMMAND(register) /* {{{ */ phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname); } else { - phpdbg_error("register", "type=\"notfoundc\" function=\"%s\"", "The requested function (%s) could not be found", param->str); + phpdbg_error("register", "type=\"notfound\" function=\"%s\"", "The requested function (%s) could not be found", param->str); } } else { phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname); diff --git a/sapi/phpdbg/phpdbg_prompt.h b/sapi/phpdbg/phpdbg_prompt.h index 94e24df833..f583f2cdcd 100644 --- a/sapi/phpdbg/phpdbg_prompt.h +++ b/sapi/phpdbg/phpdbg_prompt.h @@ -22,6 +22,7 @@ #define PHPDBG_PROMPT_H /* {{{ */ +void phpdbg_string_init(char *buffer TSRMLS_DC); void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC); void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC); int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC); |