From 488dd317feacd0ea3a9419e80eb8183ff2879c91 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 11 Dec 2013 21:27:03 +0100 Subject: [PATCH 001/137] First non-working test of segfault handlers --- config.m4 | 2 +- config.w32 | 2 +- phpdbg.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ phpdbg.h | 13 +++++++++++++ phpdbg_prompt.c | 14 ++++++++++++++ phpdbg_prompt.h | 3 ++- 6 files changed, 74 insertions(+), 9 deletions(-) diff --git a/config.m4 b/config.m4 index 274e6409d04..3016a2075df 100644 --- a/config.m4 +++ b/config.m4 @@ -18,7 +18,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/config.w32 b/config.w32 index 29031507b31..d97873ec85d 100644 --- a/config.w32 +++ b/config.w32 @@ -1,7 +1,7 @@ ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); -PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c'; +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.c b/phpdbg.c index 7a5cd48e439..d72133b2186 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -765,6 +765,26 @@ int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*sock } /* }}} */ #endif +void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) { + int is_handled = FAILURE; + TSRMLS_FETCH(); + + switch (sig) { + case SIGBUS: + case SIGSEGV: + is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC); + if (is_handled == FAILURE) { +#ifdef ZEND_SIGNALS + zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL TSRMLS_CC); +#else + sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL); +#endif + } + break; + } + +} + int main(int argc, char **argv) /* {{{ */ { sapi_module_struct *phpdbg = &phpdbg_sapi_module; @@ -802,6 +822,10 @@ int main(int argc, char **argv) /* {{{ */ void ***tsrm_ls; #endif + struct sigaction signal_struct; + signal_struct.sa_sigaction = phpdbg_signal_handler; + signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; + #ifndef _WIN32 address = strdup("127.0.0.1"); socket[0] = -1; @@ -825,7 +849,9 @@ int main(int argc, char **argv) /* {{{ */ tsrm_startup(1, 1, 0, NULL); tsrm_ls = ts_resource(0); -#endif +#endif + + phpdbg_setup_watchpoints(); phpdbg_main: if (!cleaning) { @@ -1061,17 +1087,28 @@ phpdbg_main: if (phpdbg->startup(phpdbg) == SUCCESS) { zend_activate(TSRMLS_C); - + +#ifdef ZEND_SIGNALS + zend_try { + zend_signal_activate(TSRMLS_C); + } zend_end_try(); +#endif + +#ifdef ZEND_SIGNALS + zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); + zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); +#else + sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); + sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); +#endif + /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifdef ZEND_SIGNALS # ifndef _WIN32 if (listen[0] < 0) { # endif - zend_try { - zend_signal_activate(TSRMLS_C); - zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); - } zend_end_try(); + zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try(); # ifndef _WIN32 } # endif diff --git a/phpdbg.h b/phpdbg.h index 7d2b5b5e0c9..906b894f263 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -38,6 +38,7 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" +#include "zend_signal.h" #include "SAPI.h" #include #include @@ -67,6 +68,7 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_watch.h" #ifdef ZTS # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) @@ -159,12 +161,23 @@ #define PHPDBG_IO_FDS 3 /* }}} */ /* {{{ structs */ +typedef union _phpdbg_btree phpdbg_btree; +union _phpdbg_btree { + phpdbg_btree *branches[2]; + phpdbg_watchpoint_t *watchpoint; +}; + ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ + struct sigaction old_sigsegv_signal; /* segv signal handler */ + + phpdbg_btree *watchpoint_tree; /* tree with watchpoints */ + HashTable watchpoints; /* watchpoints */ + char *exec; /* file to execute */ size_t exec_len; /* size of exec */ zend_op_array *ops; /* op_array */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c42b8d1efb1..07b9f1400ee 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -63,6 +63,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 1), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', NULL, 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -1012,6 +1013,19 @@ PHPDBG_COMMAND(list) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_COMMAND(watch) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 0bb2cc957f8..523fa6ad3cc 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -52,7 +52,8 @@ PHPDBG_COMMAND(shell); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); PHPDBG_COMMAND(register); -PHPDBG_COMMAND(quit); /* }}} */ +PHPDBG_COMMAND(quit); +PHPDBG_COMMAND(watch); /* }}} */ /* {{{ prompt commands */ extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */ From 2e5d78192eb4727dff34aba9275cd4dc9230f38c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 11 Dec 2013 21:31:22 +0100 Subject: [PATCH 002/137] Committed the damned new files --- phpdbg_watch.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_watch.h | 43 +++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 phpdbg_watch.c create mode 100644 phpdbg_watch.h diff --git a/phpdbg_watch.c b/phpdbg_watch.c new file mode 100644 index 00000000000..e54431f3e01 --- /dev/null +++ b/phpdbg_watch.c @@ -0,0 +1,69 @@ +#include "zend.h" +#include "phpdbg.h" +#include "phpdbg_watch.h" +#include +#include + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +long phpdbg_pagesize; + +void phpdbg_setup_watchpoints() { +#ifdef _SC_PAGE_SIZE + phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); +#endif +#ifdef _SC_PAGESIZE + phpdbg_pagesize = sysconf(_SC_PAGESIZE); +#endif +#ifdef _SC_NUTC_OS_PAGESIZE + phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); +#endif +} + +int phpdbg_check_for_watchpoint(void *addr) { + return FAILURE; +} + +int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { + printf("Text"); + return FAILURE; +} + +void phpdbg_create_addr_watchpoint(void *addr, size_t size) { + int m; + + /* pagesize is assumed to be in the range of 2^x */ + m= mprotect((void *)((unsigned long)addr & ~(phpdbg_pagesize - 1)), ((size - 1) & ~(phpdbg_pagesize - 1)) | phpdbg_pagesize, PROT_NONE | PROT_READ); + + printf("\n!!!!!\n%d\n!!!!!\n", m); +} + +void phpdbg_create_zval_watchpoint(zval *zv) { + phpdbg_create_addr_watchpoint(zv, sizeof(zval)); +} + +int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { + zval *zv; + + if (!EG(active_op_array)) { + phpdbg_error("No active op array!"); + return SUCCESS; + } + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + + if (!EG(active_symbol_table)) { + phpdbg_error("No active symbol table!"); + return SUCCESS; + } + } + + /* Lookup current symbol table */ + if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { + phpdbg_create_zval_watchpoint(zv); + return SUCCESS; + } + + return FAILURE; +} diff --git a/phpdbg_watch.h b/phpdbg_watch.h new file mode 100644 index 00000000000..3d142070b35 --- /dev/null +++ b/phpdbg_watch.h @@ -0,0 +1,43 @@ +#ifndef PHPDBG_WATCH_H +#define PHPDBG_WATCH_H + +#include "TSRM.h" +#include "phpdbg_cmd.h" + +#define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name) + +/** +* Printer Forward Declarations +*/ +/*PHPDBG_WATCH();*/ + + +/* Watchpoint functions/typedefs */ + +typedef enum { + WATCH_ON_ZVAL, + WATCH_ON_HASHTABLE, + WATCH_ON_PTR +} phpdbg_watchtype; + +typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; + +struct _phpdbg_watchpoint_t { + phpdbg_watchpoint_t *parent; + char *str; + union { + zval *zv; + HashTable *ht; + void *ptr; + } addr; + int size; + phpdbg_watchtype type; +}; + +void phpdbg_setup_watchpoints(); + +int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC); + +int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC); + +#endif From 85b97c0f7053df210bfb358fdd3643cf5ebf453c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 13 Dec 2013 17:57:36 -0500 Subject: [PATCH 003/137] Finished working for today, continuing tomorrow (not working) --- phpdbg.c | 2 +- phpdbg.h | 1 + phpdbg_prompt.c | 7 +++ phpdbg_watch.c | 150 ++++++++++++++++++++++++++++++++++++++++++++---- phpdbg_watch.h | 26 ++++++++- 5 files changed, 171 insertions(+), 15 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index d72133b2186..147a66e55a3 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -153,7 +153,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0); - + zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0); zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0); diff --git a/phpdbg.h b/phpdbg.h index 906b894f263..f11176325b2 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -177,6 +177,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) phpdbg_btree *watchpoint_tree; /* tree with watchpoints */ HashTable watchpoints; /* watchpoints */ + zend_llist watchlist_mem; /* triggered watchpoints */ char *exec; /* file to execute */ size_t exec_len; /* size of exec */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 07b9f1400ee..626177fa4ea 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1291,6 +1291,13 @@ zend_vm_enter: phpdbg_print_opline_ex( execute_data, &vars, 0 TSRMLS_CC); + /* check if some watchpoint was hit */ + { + if (phpdbg_print_changed_zvals(TSRMLS_C) == SUCCESS) { + DO_INTERACTIVE(); + } + } + /* search for breakpoints */ { phpdbg_breakbase_t *brake; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index e54431f3e01..66721ee8e65 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -1,3 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + #include "zend.h" #include "phpdbg.h" #include "phpdbg_watch.h" @@ -8,7 +28,20 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); long phpdbg_pagesize; -void phpdbg_setup_watchpoints() { +typedef struct { + void *page; + size_t size; + /* data must be last element */ + void *data; +} phpdbg_watch_memdump; + +#define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) + +void phpdbg_watch_mem_dtor(void *llist_data) { + efree(llist_data); +} + +void phpdbg_setup_watchpoints(TSRMLS_D) { #ifdef _SC_PAGE_SIZE phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); #endif @@ -18,32 +51,124 @@ void phpdbg_setup_watchpoints() { #ifdef _SC_NUTC_OS_PAGESIZE phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); #endif + + zend_llist_init(&PHPDBG_G(watchlist_mem), 0, phpdbg_watch_mem_dtor, 0); } -int phpdbg_check_for_watchpoint(void *addr) { - return FAILURE; +void *phpdbg_get_page_boundary(void *addr) { + return (void *)((unsigned long)addr & ~(phpdbg_pagesize - 1)); +} + +size_t phpdbg_get_total_page_size(size_t size) { + return ((size - 1) & ~(phpdbg_pagesize - 1)) | phpdbg_pagesize; +} + +phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr) { + phpdbg_watchpoint_t *watch; + + /* find nearest watchpoint */ + + /* check if that watchpoint includes addr */ + if (((char *)watch->addr.ptr) + watch->size > (char *)addr) { + /* failure */ + return NULL; + } + + return watch; } int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { - printf("Text"); - return FAILURE; + void *addr; + void *page; + phpdbg_watch_memdump *dump; + phpdbg_watchpoint_t *watch; + size_t size; + + addr = info->si_addr; + + watch = phpdbg_check_for_watchpoint(addr); + + if (watch == NULL) { + return FAILURE; + } + + page = phpdbg_get_page_boundary(addr); + size = phpdbg_get_total_page_size(watch->size); + + /* re-enable writing */ + mprotect(page, size, PROT_NONE | PROT_READ | PROT_WRITE); + + dump = emalloc(MEMDUMP_SIZE(size)); + + memcpy(&dump->data, page, size); + + zend_llist_add_element(&PHPDBG_G(watchlist_mem), dump); + + return SUCCESS; } -void phpdbg_create_addr_watchpoint(void *addr, size_t size) { +int phpdbg_print_changed_zval(void *llist_data) { + phpdbg_watch_memdump *dump = llist_data; + phpdbg_watchpoint_t *watch; + phpdbg_btree *tree = PHPDBG_G(watchpoint_tree); + void *oldPtr; + + TSRMLS_FETCH(); + + /* fetch all changes between dump->page and dump->page + dump->size */ + watch = tree->watchpoint; + oldPtr = (char *)dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + if (memcmp(oldPtr, watch->addr.ptr, watch->size) == SUCCESS) { + phpdbg_notice("Breaking on watchpoint %s", watch->str); + switch (watch->type) { + case WATCH_ON_ZVAL: + phpdbg_write("Old value: "); + zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + phpdbg_write("New value: "); + zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); + break; + } + } + + + return 1; +} + +int phpdbg_print_changed_zvals(TSRMLS_D) { + if (zend_llist_count(&PHPDBG_G(watchlist_mem)) == 0) { + return FAILURE; + } + + zend_llist_apply_with_del(&PHPDBG_G(watchlist_mem), phpdbg_print_changed_zval); + + return SUCCESS; +} + +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { int m; - /* pagesize is assumed to be in the range of 2^x */ - m= mprotect((void *)((unsigned long)addr & ~(phpdbg_pagesize - 1)), ((size - 1) & ~(phpdbg_pagesize - 1)) | phpdbg_pagesize, PROT_NONE | PROT_READ); + watch->addr.ptr = addr; + watch->size = size; + watch->type = WATCH_ON_PTR; - printf("\n!!!!!\n%d\n!!!!!\n", m); + /* pagesize is assumed to be in the range of 2^x */ + m = mprotect(phpdbg_get_page_boundary(addr), phpdbg_get_total_page_size(size), PROT_NONE | PROT_READ); + + if (m == FAILURE) { + phpdbg_error("Unable to set watchpoint (mprotect() failed)"); + zend_bailout(); + } } -void phpdbg_create_zval_watchpoint(zval *zv) { - phpdbg_create_addr_watchpoint(zv, sizeof(zval)); +void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { + phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); + watch->type = WATCH_ON_ZVAL; } int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { zval *zv; + phpdbg_watchpoint_t watch; + if (!EG(active_op_array)) { phpdbg_error("No active op array!"); @@ -61,7 +186,8 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { /* Lookup current symbol table */ if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { - phpdbg_create_zval_watchpoint(zv); + phpdbg_create_zval_watchpoint(zv, &watch); + zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t), NULL); return SUCCESS; } diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 3d142070b35..81a2f741ea6 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -1,3 +1,23 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + #ifndef PHPDBG_WATCH_H #define PHPDBG_WATCH_H @@ -30,14 +50,16 @@ struct _phpdbg_watchpoint_t { HashTable *ht; void *ptr; } addr; - int size; + size_t size; phpdbg_watchtype type; }; -void phpdbg_setup_watchpoints(); +void phpdbg_setup_watchpoints(TSRMLS_D); int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC); int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC); +int phpdbg_print_changed_zvals(TSRMLS_D); + #endif From f312f6bad24770e0587c0d06723d22cac691056c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 14 Dec 2013 05:39:09 -0500 Subject: [PATCH 004/137] First semi-working version of a single watchpoint --- phpdbg.c | 2 + phpdbg.h | 1 + phpdbg_watch.c | 192 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 164 insertions(+), 31 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 147a66e55a3..fc817694f39 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -154,6 +154,8 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0); + zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, NULL, 0); /* TODO: dtor */ + zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0); zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0); diff --git a/phpdbg.h b/phpdbg.h index f11176325b2..50149767958 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -178,6 +178,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) phpdbg_btree *watchpoint_tree; /* tree with watchpoints */ HashTable watchpoints; /* watchpoints */ zend_llist watchlist_mem; /* triggered watchpoints */ + zend_bool watchpoint_hit; /* a watchpoint was hit */ char *exec; /* file to execute */ size_t exec_len; /* size of exec */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 66721ee8e65..00c83b5717b 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -37,8 +37,18 @@ typedef struct { #define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) +#define CHOOSE_BRANCH(n) \ + addr = (addr << 1) + !!(n); \ + branch = branch->branches[!!(n)]; + void phpdbg_watch_mem_dtor(void *llist_data) { - efree(llist_data); + void *page = (*(phpdbg_watch_memdump **)llist_data)->page; + size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; + + efree(*(void **)llist_data); + + /* Disble writing again */ + mprotect(page, size, PROT_NONE | PROT_READ); } void phpdbg_setup_watchpoints(TSRMLS_D) { @@ -52,24 +62,64 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); #endif - zend_llist_init(&PHPDBG_G(watchlist_mem), 0, phpdbg_watch_mem_dtor, 0); + zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); } void *phpdbg_get_page_boundary(void *addr) { - return (void *)((unsigned long)addr & ~(phpdbg_pagesize - 1)); + return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); } -size_t phpdbg_get_total_page_size(size_t size) { - return ((size - 1) & ~(phpdbg_pagesize - 1)) | phpdbg_pagesize; +size_t phpdbg_get_total_page_size(void *addr, size_t size) { + return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } -phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr) { +phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr) { phpdbg_watchpoint_t *watch; + phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); + int i = sizeof(void *) * 8 - 1, last_superior_i = -1; + size_t addr = 0; + size_t opline = (size_t)phpdbg_get_page_boundary(watch_addr) + phpdbg_pagesize - 1; /* find nearest watchpoint */ + do { + /* an impossible branch was found if: */ + if ((opline >> i) % 2 == 0 && !branch->branches[0]) { + /* there's no lower branch than opline */ + if (last_superior_i == -1) { + /* failure */ + return NULL; + } + /* reset state */ + branch = PHPDBG_G(watchpoint_tree); + addr = 0; + i = sizeof(void *) * 8 - 1; + /* follow branch according to bits in opline until the last lower branch before the impossible branch */ + do { + CHOOSE_BRANCH((opline >> i) % 2 == 1 && branch->branches[1]); + } while (--i > last_superior_i); + /* use now the lower branch of which we can be sure that it contains only branches lower than opline */ + CHOOSE_BRANCH(0); + /* and choose the highest possible branch in the branch containing only branches lower than opline */ + while (i--) { + CHOOSE_BRANCH(branch->branches[1]); + } + break; + } + /* follow branch according to bits in opline until having found an impossible branch */ + if ((opline >> i) % 2 == 1 && branch->branches[1]) { + if (branch->branches[0]) { + last_superior_i = i; + } + CHOOSE_BRANCH(1); + } else { + CHOOSE_BRANCH(0); + } + } while (i--); - /* check if that watchpoint includes addr */ - if (((char *)watch->addr.ptr) + watch->size > (char *)addr) { + watch = branch->watchpoint; + + /* check if that addr is in a mprotect()'ed memory area */ + if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) { /* failure */ return NULL; } @@ -93,43 +143,97 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) } page = phpdbg_get_page_boundary(addr); - size = phpdbg_get_total_page_size(watch->size); + size = phpdbg_get_total_page_size(addr, watch->size); /* re-enable writing */ mprotect(page, size, PROT_NONE | PROT_READ | PROT_WRITE); dump = emalloc(MEMDUMP_SIZE(size)); + dump->page = page; + dump->size = size; memcpy(&dump->data, page, size); - zend_llist_add_element(&PHPDBG_G(watchlist_mem), dump); + zend_llist_add_element(&PHPDBG_G(watchlist_mem), &dump); return SUCCESS; } int phpdbg_print_changed_zval(void *llist_data) { - phpdbg_watch_memdump *dump = llist_data; - phpdbg_watchpoint_t *watch; - phpdbg_btree *tree = PHPDBG_G(watchpoint_tree); + phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; void *oldPtr; + size_t opline; TSRMLS_FETCH(); /* fetch all changes between dump->page and dump->page + dump->size */ - watch = tree->watchpoint; - oldPtr = (char *)dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); - if (memcmp(oldPtr, watch->addr.ptr, watch->size) == SUCCESS) { - phpdbg_notice("Breaking on watchpoint %s", watch->str); - switch (watch->type) { - case WATCH_ON_ZVAL: - phpdbg_write("Old value: "); - zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); - phpdbg_write("New value: "); - zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); + opline = (size_t)dump->page + dump->size - 1; + + while (1) { + phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); + phpdbg_watchpoint_t *watch; + int i = sizeof(void *) * 8 - 1, last_superior_i = -1; + size_t addr = 0; + + do { + /* an impossible branch was found if: */ + if ((opline >> i) % 2 == 0 && !branch->branches[0]) { + /* there's no lower branch than opline */ + if (last_superior_i == -1) { + return 1; + } + /* reset state */ + branch = PHPDBG_G(watchpoint_tree); + addr = 0; + i = sizeof(void *) * 8 - 1; + /* follow branch according to bits in opline until the last lower branch before the impossible branch */ + do { + CHOOSE_BRANCH((opline >> i) % 2 == 1 && branch->branches[1]); + } while (--i > last_superior_i); + /* use now the lower branch of which we can be sure that it contains only branches lower than opline */ + CHOOSE_BRANCH(0); + /* and choose the highest possible branch in the branch containing only branches lower than opline */ + while (i--) { + CHOOSE_BRANCH(branch->branches[1]); + } break; + } + /* follow branch according to bits in opline until having found an impossible branch */ + if ((opline >> i) % 2 == 1 && branch->branches[1]) { + if (branch->branches[0]) { + last_superior_i = i; + } + CHOOSE_BRANCH(1); + } else { + CHOOSE_BRANCH(0); + } + } while (i--); + + if (watch == branch->watchpoint) + return 1; /* TODO: there's sometime wrong with the breaking condition ... */ + + watch = branch->watchpoint; + oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { + PHPDBG_G(watchpoint_hit) = 1; + + phpdbg_notice("Breaking on watchpoint %s", watch->str); + switch (watch->type) { + case WATCH_ON_ZVAL: + phpdbg_write("Old value: "); + zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + phpdbg_writeln(""); + phpdbg_write("New value: "); + zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); + phpdbg_writeln(""); + break; + } + } else { + break; } + + opline = (size_t)watch->addr.ptr - 1; } - return 1; } @@ -139,9 +243,33 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { return FAILURE; } + PHPDBG_G(watchpoint_hit) = 0; zend_llist_apply_with_del(&PHPDBG_G(watchlist_mem), phpdbg_print_changed_zval); - return SUCCESS; + return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; +} + +void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree **branch = &PHPDBG_G(watchpoint_tree); + int i = sizeof(void *) * 8 - 1; + + do { + if (*branch == NULL) { + break; + } + branch = &(*branch)->branches[((size_t)watch->addr.ptr >> i) % 2]; + } while (i--); + + if (*branch == NULL) { + phpdbg_btree *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree)); + do { + (*branch)->branches[!(((size_t)watch->addr.ptr >> i) % 2)] = NULL; + branch = &(*branch)->branches[((size_t)watch->addr.ptr >> i) % 2]; + *branch = ++memory; + } while (i--); + } + + (*branch)->watchpoint = watch; } void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { @@ -152,7 +280,7 @@ void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t watch->type = WATCH_ON_PTR; /* pagesize is assumed to be in the range of 2^x */ - m = mprotect(phpdbg_get_page_boundary(addr), phpdbg_get_total_page_size(size), PROT_NONE | PROT_READ); + m = mprotect(phpdbg_get_page_boundary(addr), phpdbg_get_total_page_size(addr, size), PROT_NONE | PROT_READ); if (m == FAILURE) { phpdbg_error("Unable to set watchpoint (mprotect() failed)"); @@ -166,9 +294,8 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { } int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { - zval *zv; - phpdbg_watchpoint_t watch; - + zval **zv; + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); if (!EG(active_op_array)) { phpdbg_error("No active op array!"); @@ -184,10 +311,13 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { } } + watch->str = estrndup(name, len); + /* Lookup current symbol table */ if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { - phpdbg_create_zval_watchpoint(zv, &watch); - zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t), NULL); + zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + phpdbg_store_watchpoint(watch TSRMLS_CC); + phpdbg_create_zval_watchpoint(*zv, watch); return SUCCESS; } From 0ca7f72130b117ba0d31c093c53b951dfd9e960e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 15 Dec 2013 11:55:03 -0200 Subject: [PATCH 005/137] - Fixed build --- phpdbg.c | 104 ++++++++++++++++++++++++------------------------- phpdbg_watch.c | 12 +++--- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index fc817694f39..7c80b591e36 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -207,24 +207,24 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ return SUCCESS; } /* }}} */ -/* {{{ proto mixed phpdbg_exec(string context) +/* {{{ proto mixed phpdbg_exec(string context) Attempt to set the execution context for phpdbg If the execution context was set previously it is returned - If the execution context was not set previously boolean true is returned + If the execution context was not set previously boolean true is returned If the request to set the context fails, boolean false is returned, and an E_WARNING raised */ -static PHP_FUNCTION(phpdbg_exec) +static PHP_FUNCTION(phpdbg_exec) { char *exec = NULL; zend_ulong exec_len = 0L; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) { return; } - + { struct stat sb; zend_bool result = 1; - + if (VCWD_STAT(exec, &sb) != FAILURE) { if (sb.st_mode & (S_IFREG|S_IFLNK)) { if (PHPDBG_G(exec)) { @@ -232,11 +232,11 @@ static PHP_FUNCTION(phpdbg_exec) efree(PHPDBG_G(exec)); result = 0; } - + PHPDBG_G(exec) = estrndup(exec, exec_len); PHPDBG_G(exec_len) = exec_len; - - if (result) + + if (result) ZVAL_BOOL(return_value, 1); } else { zend_error( @@ -401,9 +401,9 @@ static inline int php_sapi_phpdbg_module_startup(sapi_module_struct *module) /* if (php_module_startup(module, &sapi_phpdbg_module_entry, 1) == FAILURE) { return FAILURE; } - + phpdbg_booted=1; - + return SUCCESS; } /* }}} */ @@ -625,11 +625,11 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ { int fd = socket(AF_INET, SOCK_STREAM, 0); - + switch (fd) { case -1: return -1; - + default: { int reuse = 1; @@ -637,27 +637,27 @@ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ case -1: close(fd); return -2; - + default: { struct sockaddr_in address; - + memset(&address, 0, sizeof(address)); - + address.sin_port = htons(port); address.sin_family = AF_INET; - + if ((*interface == '*')) { - address.sin_addr.s_addr = htonl(INADDR_ANY); + address.sin_addr.s_addr = htonl(INADDR_ANY); } else if (!inet_pton(AF_INET, interface, &address.sin_addr)) { close(fd); return -3; } - + switch (bind(fd, (struct sockaddr *)&address, sizeof(address))) { case -1: close(fd); return -4; - + default: { listen(fd, 5); } @@ -666,28 +666,28 @@ int phpdbg_open_socket(const char *interface, short port) /* {{{ */ } } } - + return fd; } /* }}} */ static inline void phpdbg_close_sockets(int (*socket)[2], FILE *streams[2]) /* {{{ */ -{ +{ if ((*socket)[0] >= 0) { shutdown( (*socket)[0], SHUT_RDWR); close((*socket)[0]); } - + if (streams[0]) { fclose(streams[0]); } - + if ((*socket)[1] >= 0) { shutdown( (*socket)[1], SHUT_RDWR); close((*socket)[1]); } - + if (streams[1]) { fclose(streams[1]); } @@ -757,12 +757,12 @@ int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*sock dup2((*socket)[0], fileno(stdin)); dup2((*socket)[1], fileno(stdout)); - + setbuf(stdout, NULL); streams[0] = fdopen((*socket)[0], "r"); streams[1] = fdopen((*socket)[1], "w"); - + return SUCCESS; } /* }}} */ #endif @@ -851,9 +851,9 @@ int main(int argc, char **argv) /* {{{ */ tsrm_startup(1, 1, 0, NULL); tsrm_ls = ts_resource(0); -#endif +#endif - phpdbg_setup_watchpoints(); + phpdbg_setup_watchpoints(TSRMLS_C); phpdbg_main: if (!cleaning) { @@ -883,8 +883,8 @@ phpdbg_main: run = 0; step = 0; sapi_name = NULL; - - + + while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (opt) { case 'r': @@ -928,7 +928,7 @@ phpdbg_main: ini_entries_len += len + sizeof("=1\n\0") - 2; } } break; - + case 'z': zend_extensions_len++; if (zend_extensions) { @@ -948,7 +948,7 @@ phpdbg_main: exec = strdup(php_optarg); } } break; - + case 'S': { /* set SAPI name */ if (sapi_name) { free(sapi_name); @@ -964,7 +964,7 @@ phpdbg_main: if (init_file) { free(init_file); } - + init_file_len = strlen(php_optarg); if (init_file_len) { init_file = strdup(php_optarg); @@ -1001,7 +1001,7 @@ phpdbg_main: #ifndef _WIN32 /* if you pass a listen port, we will accept input on listen port */ /* and write output to listen port * 2 */ - + case 'l': { /* set listen ports */ if (sscanf(php_optarg, "%d/%d", &listen[0], &listen[1]) != 2) { if (sscanf(php_optarg, "%d", &listen[0]) != 1) { @@ -1013,7 +1013,7 @@ phpdbg_main: } } } break; - + case 'a': { /* set bind address */ free(address); if (!php_optarg) { @@ -1040,7 +1040,7 @@ phpdbg_main: if (sapi_name) { phpdbg->name = sapi_name; } - + phpdbg->ini_defaults = phpdbg_ini_defaults; phpdbg->phpinfo_as_text = 1; phpdbg->php_ini_ignore_cwd = 1; @@ -1061,14 +1061,14 @@ phpdbg_main: memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded)); } ini_entries_len += sizeof(phpdbg_ini_hardcoded) - 2; - + if (zend_extensions_len) { zend_ulong zend_extension = 0L; - + while (zend_extension < zend_extensions_len) { const char *ze = zend_extensions[zend_extension]; size_t ze_len = strlen(ze); - + ini_entries = realloc( ini_entries, ini_entries_len + (ze_len + (sizeof("zend_extension=\n")))); memcpy(&ini_entries[ini_entries_len], "zend_extension=", (sizeof("zend_extension=\n")-1)); @@ -1080,14 +1080,14 @@ phpdbg_main: free(zend_extensions[zend_extension]); zend_extension++; } - + free(zend_extensions); } phpdbg->ini_entries = ini_entries; - + if (phpdbg->startup(phpdbg) == SUCCESS) { - + zend_activate(TSRMLS_C); #ifdef ZEND_SIGNALS @@ -1125,7 +1125,7 @@ phpdbg_main: #endif PG(modules_activated) = 0; - + /* set flags from command line */ PHPDBG_G(flags) = flags; @@ -1141,7 +1141,7 @@ phpdbg_main: PHPDBG_G(io)[PHPDBG_STDIN] = stdin; PHPDBG_G(io)[PHPDBG_STDOUT] = stdout; PHPDBG_G(io)[PHPDBG_STDERR] = stderr; - + if (exec) { /* set execution context */ PHPDBG_G(exec) = phpdbg_resolve_path( exec TSRMLS_CC); @@ -1230,12 +1230,12 @@ phpdbg_interact: /* renegociate connections */ phpdbg_open_sockets( address, listen, &server, &socket, streams); - + /* set streams */ if (streams[0] && streams[1]) { PHPDBG_G(flags) &= ~PHPDBG_IS_QUITTING; } - + /* this must be forced */ CG(unclean_shutdown) = 0; } @@ -1245,10 +1245,10 @@ phpdbg_interact: } } zend_end_try(); } while(!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); - + /* this must be forced */ CG(unclean_shutdown) = 0; - + phpdbg_out: #ifndef _WIN32 if (PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED) { @@ -1256,7 +1256,7 @@ phpdbg_out: goto phpdbg_interact; } #endif - + if (ini_entries) { free(ini_entries); } @@ -1301,14 +1301,14 @@ phpdbg_out: #ifndef _WIN32 if (address) { - free(address); + free(address); } #endif if (sapi_name) { free(sapi_name); } - + free(bp_tmp_file); return 0; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 00c83b5717b..38a74bda15a 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -73,7 +73,7 @@ size_t phpdbg_get_total_page_size(void *addr, size_t size) { return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } -phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr) { +phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr TSRMLS_DC) { phpdbg_watchpoint_t *watch; phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); int i = sizeof(void *) * 8 - 1, last_superior_i = -1; @@ -136,7 +136,7 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) addr = info->si_addr; - watch = phpdbg_check_for_watchpoint(addr); + watch = phpdbg_check_for_watchpoint(addr TSRMLS_CC); if (watch == NULL) { return FAILURE; @@ -272,7 +272,7 @@ void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { (*branch)->watchpoint = watch; } -void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch TSRMLS_DC) { int m; watch->addr.ptr = addr; @@ -288,8 +288,8 @@ void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t } } -void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { - phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); +void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch TSRMLS_CC); watch->type = WATCH_ON_ZVAL; } @@ -317,7 +317,7 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); phpdbg_store_watchpoint(watch TSRMLS_CC); - phpdbg_create_zval_watchpoint(*zv, watch); + phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); return SUCCESS; } From 75b4b4676bfc275a27c272122fee7d92d65109d8 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 15 Dec 2013 11:58:14 -0200 Subject: [PATCH 006/137] - Staticfy some functions --- phpdbg_watch.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 38a74bda15a..dd4384f315e 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -41,7 +41,7 @@ typedef struct { addr = (addr << 1) + !!(n); \ branch = branch->branches[!!(n)]; -void phpdbg_watch_mem_dtor(void *llist_data) { +static void phpdbg_watch_mem_dtor(void *llist_data) { void *page = (*(phpdbg_watch_memdump **)llist_data)->page; size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; @@ -65,15 +65,15 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); } -void *phpdbg_get_page_boundary(void *addr) { +static inline void *phpdbg_get_page_boundary(void *addr) { return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); } -size_t phpdbg_get_total_page_size(void *addr, size_t size) { +static inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } -phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr TSRMLS_DC) { +static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr TSRMLS_DC) { phpdbg_watchpoint_t *watch; phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); int i = sizeof(void *) * 8 - 1, last_superior_i = -1; @@ -159,7 +159,7 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) return SUCCESS; } -int phpdbg_print_changed_zval(void *llist_data) { +static int phpdbg_print_changed_zval(void *llist_data) { phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; void *oldPtr; size_t opline; @@ -249,7 +249,7 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; } -void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { +static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_btree **branch = &PHPDBG_G(watchpoint_tree); int i = sizeof(void *) * 8 - 1; @@ -272,7 +272,7 @@ void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { (*branch)->watchpoint = watch; } -void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch TSRMLS_DC) { +static void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch TSRMLS_DC) { int m; watch->addr.ptr = addr; @@ -288,7 +288,7 @@ void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t } } -void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch TSRMLS_DC) { +static void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch TSRMLS_CC); watch->type = WATCH_ON_ZVAL; } From 9ce9f48fb6db47219662d70504c386cbf7fea980 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 15 Dec 2013 09:05:50 -0500 Subject: [PATCH 007/137] Moved btree to separate file; minor fixes and completitions --- config.m4 | 2 +- config.w32 | 2 +- phpdbg.h | 9 +-- phpdbg_btree.c | 198 +++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_btree.h | 64 ++++++++++++++++ phpdbg_watch.c | 156 +++++++------------------------------- 6 files changed, 291 insertions(+), 140 deletions(-) create mode 100644 phpdbg_btree.c create mode 100644 phpdbg_btree.h diff --git a/config.m4 b/config.m4 index 3016a2075df..9e2d2105805 100644 --- a/config.m4 +++ b/config.m4 @@ -18,7 +18,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/config.w32 b/config.w32 index d97873ec85d..5813e7f1564 100644 --- a/config.w32 +++ b/config.w32 @@ -1,7 +1,7 @@ ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); -PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c'; +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.h b/phpdbg.h index 50149767958..abbb5b8a7a6 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -68,6 +68,7 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_btree.h" #include "phpdbg_watch.h" #ifdef ZTS @@ -161,12 +162,6 @@ #define PHPDBG_IO_FDS 3 /* }}} */ /* {{{ structs */ -typedef union _phpdbg_btree phpdbg_btree; -union _phpdbg_btree { - phpdbg_btree *branches[2]; - phpdbg_watchpoint_t *watchpoint; -}; - ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ HashTable registered; /* registered */ @@ -175,7 +170,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) struct sigaction old_sigsegv_signal; /* segv signal handler */ - phpdbg_btree *watchpoint_tree; /* tree with watchpoints */ + phpdbg_btree watchpoint_tree; /* tree with watchpoints */ HashTable watchpoints; /* watchpoints */ zend_llist watchlist_mem; /* triggered watchpoints */ zend_bool watchpoint_hit; /* a watchpoint was hit */ diff --git a/phpdbg_btree.c b/phpdbg_btree.c new file mode 100644 index 00000000000..f47422f4630 --- /dev/null +++ b/phpdbg_btree.c @@ -0,0 +1,198 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "phpdbg_btree.h" +#include "phpdbg.h" + +#define CHOOSE_BRANCH(n) \ + branch = branch->branches[!!(n)]; + +/* depth in bits */ +void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth) { + tree->depth = depth; + tree->branch = NULL; +} + +phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx) { + phpdbg_btree_branch *branch = tree->branch; + int i = tree->depth - 1; + + do { + if ((idx >> i) % 2 == 1) { + if (branch->branches[1]) { + CHOOSE_BRANCH(1); + } else { + return NULL; + } + } else { + if (branch->branches[0]) { + CHOOSE_BRANCH(0); + } else { + return NULL; + } + } + } while (i--); + + return &branch->result; +} + +phpdbg_btree_result *phpdbg_btree_find_closest(phpdbg_btree *tree, zend_ulong idx) { + phpdbg_btree_branch *branch = tree->branch; + int i = tree->depth - 1, last_superior_i = -1; + zend_bool had_alternative_branch = 0; + + if (branch == NULL) { + return NULL; + } + + /* find nearest watchpoint */ + do { + /* an impossible branch was found if: */ + if (!had_alternative_branch && (idx >> i) % 2 == 0 && !branch->branches[0]) { + /* there's no lower branch than idx */ + if (last_superior_i == -1) { + /* failure */ + return NULL; + } + /* reset state */ + branch = tree->branch; + i = sizeof(void *) * 8 - 1; + /* follow branch according to bits in idx until the last lower branch before the impossible branch */ + do { + CHOOSE_BRANCH((idx >> i) % 2 == 1 && branch->branches[1]); + } while (--i > last_superior_i); + /* use now the lower branch of which we can be sure that it contains only branches lower than idx */ + CHOOSE_BRANCH(0); + /* and choose the highest possible branch in the branch containing only branches lower than idx */ + while (i--) { + CHOOSE_BRANCH(branch->branches[1]); + } + break; + } + /* follow branch according to bits in idx until having found an impossible branch */ + if (had_alternative_branch || (idx >> i) % 2 == 1) { + if (branch->branches[1]) { + if (branch->branches[0]) { + last_superior_i = i; + } + CHOOSE_BRANCH(1); + } else { + CHOOSE_BRANCH(0); + had_alternative_branch = 1; + } + } else { + CHOOSE_BRANCH(0); + } + } while (i--); + + return &branch->result; +} + +phpdbg_btree_position phpdbg_btree_find_between(phpdbg_btree *tree, zend_ulong lower_idx, zend_ulong higher_idx) { + phpdbg_btree_position pos; + + pos.tree = tree; + pos.end = lower_idx; + pos.cur = higher_idx; + + return pos; +} + +phpdbg_btree_result *phpdbg_btree_next(phpdbg_btree_position *pos) { + phpdbg_btree_result *result = phpdbg_btree_find_closest(pos->tree, pos->cur); + + if (result == NULL || result->idx < pos->end) { + return NULL; + } + + pos->cur = result->idx - 1; + + return result; +} + +int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, int flags) { + int i = tree->depth - 1; + phpdbg_btree_branch **branch = &tree->branch; + + do { + if (*branch == NULL) { + break; + } + branch = &(*branch)->branches[(idx >> i) % 2]; + } while (i--); + + if (*branch == NULL) { + if (!(flags & PHPDBG_BTREE_INSERT)) { + return FAILURE; + } + + { + phpdbg_btree_branch *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree_branch)); + do { + (*branch)->branches[!((idx >> i) % 2)] = NULL; + branch = &(*branch)->branches[(idx >> i) % 2]; + *branch = ++memory; + } while (i--); + } + } else if (!(flags & PHPDBG_BTREE_UPDATE)) { + return FAILURE; + } + + (*branch)->result.idx = idx; + (*branch)->result.ptr = ptr; + + return SUCCESS; +} + +int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx) { + int i = tree->depth - 1; + phpdbg_btree_branch *branch = tree->branch; + int i_last_dual_branch = -1, last_dual_branch_branch; + phpdbg_btree_branch *last_dual_branch = NULL; + + do { + if (branch == NULL) { + return FAILURE; + } + if (branch->branches[0] && branch->branches[1]) { + last_dual_branch = branch; + i_last_dual_branch = i; + last_dual_branch_branch = (idx >> i) % 2; + } + branch = branch->branches[(idx >> i) % 2]; + } while (i--); + + if (i_last_dual_branch == -1) { + efree(tree); + tree = NULL; + } else { + if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) { + memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], i_last_dual_branch * sizeof(phpdbg_btree_branch)); + efree(last_dual_branch->branches[last_dual_branch_branch]); + last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1; + } else { + efree(last_dual_branch->branches[last_dual_branch_branch]); + } + + last_dual_branch->branches[i_last_dual_branch] = NULL; + } + + return SUCCESS; +} diff --git a/phpdbg_btree.h b/phpdbg_btree.h new file mode 100644 index 00000000000..7bb40aefca6 --- /dev/null +++ b/phpdbg_btree.h @@ -0,0 +1,64 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_BTREE_H +#define PHPDBG_BTREE_H + +#include "zend.h" + +typedef struct { + zend_ulong idx; + void *ptr; +} phpdbg_btree_result; + +typedef union _phpdbg_btree_branch phpdbg_btree_branch; +union _phpdbg_btree_branch { + phpdbg_btree_branch *branches[2]; + phpdbg_btree_result result; +}; + +typedef struct { + zend_ulong depth; + phpdbg_btree_branch *branch; +} phpdbg_btree; + +typedef struct { + phpdbg_btree *tree; + zend_ulong cur; + zend_ulong end; +} phpdbg_btree_position; + +void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth); +phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx); +phpdbg_btree_result *phpdbg_btree_find_closest(phpdbg_btree *tree, zend_ulong idx); +phpdbg_btree_position phpdbg_btree_find_between(phpdbg_btree *tree, zend_ulong lower_idx, zend_ulong higher_idx); +phpdbg_btree_result *phpdbg_btree_next(phpdbg_btree_position *pos); +int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx); + +#define PHPDBG_BTREE_INSERT 1 +#define PHPDBG_BTREE_UPDATE 2 +#define PHPDBG_BTREE_OVERWRITE (PHPDBG_BTREE_INSERT | PHPDBG_BTREE_UPDATE) + +int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, int flags); +#define phpdbg_btree_insert(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_INSERT) +#define phpdbg_btree_update(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_UPDATE) +#define phpdbg_btree_overwrite(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_OWERWRITE) + +#endif diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 00c83b5717b..66fcb8eab75 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -20,6 +20,7 @@ #include "zend.h" #include "phpdbg.h" +#include "phpdbg_btree.h" #include "phpdbg_watch.h" #include #include @@ -37,10 +38,6 @@ typedef struct { #define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) -#define CHOOSE_BRANCH(n) \ - addr = (addr << 1) + !!(n); \ - branch = branch->branches[!!(n)]; - void phpdbg_watch_mem_dtor(void *llist_data) { void *page = (*(phpdbg_watch_memdump **)llist_data)->page; size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; @@ -63,6 +60,7 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { #endif zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); + phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); } void *phpdbg_get_page_boundary(void *addr) { @@ -73,53 +71,11 @@ size_t phpdbg_get_total_page_size(void *addr, size_t size) { return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } -phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *watch_addr) { - phpdbg_watchpoint_t *watch; - phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); - int i = sizeof(void *) * 8 - 1, last_superior_i = -1; - size_t addr = 0; - size_t opline = (size_t)phpdbg_get_page_boundary(watch_addr) + phpdbg_pagesize - 1; - - /* find nearest watchpoint */ - do { - /* an impossible branch was found if: */ - if ((opline >> i) % 2 == 0 && !branch->branches[0]) { - /* there's no lower branch than opline */ - if (last_superior_i == -1) { - /* failure */ - return NULL; - } - /* reset state */ - branch = PHPDBG_G(watchpoint_tree); - addr = 0; - i = sizeof(void *) * 8 - 1; - /* follow branch according to bits in opline until the last lower branch before the impossible branch */ - do { - CHOOSE_BRANCH((opline >> i) % 2 == 1 && branch->branches[1]); - } while (--i > last_superior_i); - /* use now the lower branch of which we can be sure that it contains only branches lower than opline */ - CHOOSE_BRANCH(0); - /* and choose the highest possible branch in the branch containing only branches lower than opline */ - while (i--) { - CHOOSE_BRANCH(branch->branches[1]); - } - break; - } - /* follow branch according to bits in opline until having found an impossible branch */ - if ((opline >> i) % 2 == 1 && branch->branches[1]) { - if (branch->branches[0]) { - last_superior_i = i; - } - CHOOSE_BRANCH(1); - } else { - CHOOSE_BRANCH(0); - } - } while (i--); - - watch = branch->watchpoint; +phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr) { + phpdbg_watchpoint_t *watch = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1)->ptr; /* check if that addr is in a mprotect()'ed memory area */ - if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) { + if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) { /* failure */ return NULL; } @@ -160,60 +116,17 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) } int phpdbg_print_changed_zval(void *llist_data) { - phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; - void *oldPtr; - size_t opline; - TSRMLS_FETCH(); + phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; /* fetch all changes between dump->page and dump->page + dump->size */ - opline = (size_t)dump->page + dump->size - 1; + phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); + phpdbg_btree_result *result; - while (1) { - phpdbg_btree *branch = PHPDBG_G(watchpoint_tree); - phpdbg_watchpoint_t *watch; - int i = sizeof(void *) * 8 - 1, last_superior_i = -1; - size_t addr = 0; - do { - /* an impossible branch was found if: */ - if ((opline >> i) % 2 == 0 && !branch->branches[0]) { - /* there's no lower branch than opline */ - if (last_superior_i == -1) { - return 1; - } - /* reset state */ - branch = PHPDBG_G(watchpoint_tree); - addr = 0; - i = sizeof(void *) * 8 - 1; - /* follow branch according to bits in opline until the last lower branch before the impossible branch */ - do { - CHOOSE_BRANCH((opline >> i) % 2 == 1 && branch->branches[1]); - } while (--i > last_superior_i); - /* use now the lower branch of which we can be sure that it contains only branches lower than opline */ - CHOOSE_BRANCH(0); - /* and choose the highest possible branch in the branch containing only branches lower than opline */ - while (i--) { - CHOOSE_BRANCH(branch->branches[1]); - } - break; - } - /* follow branch according to bits in opline until having found an impossible branch */ - if ((opline >> i) % 2 == 1 && branch->branches[1]) { - if (branch->branches[0]) { - last_superior_i = i; - } - CHOOSE_BRANCH(1); - } else { - CHOOSE_BRANCH(0); - } - } while (i--); - - if (watch == branch->watchpoint) - return 1; /* TODO: there's sometime wrong with the breaking condition ... */ - - watch = branch->watchpoint; - oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + while ((result = phpdbg_btree_next(&pos))) { + phpdbg_watchpoint_t *watch = result->ptr; + void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { PHPDBG_G(watchpoint_hit) = 1; @@ -222,17 +135,13 @@ int phpdbg_print_changed_zval(void *llist_data) { case WATCH_ON_ZVAL: phpdbg_write("Old value: "); zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); - phpdbg_writeln(""); + phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); phpdbg_write("New value: "); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); - phpdbg_writeln(""); + phpdbg_writeln("\nNew refcount: %d; Old is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); break; } - } else { - break; } - - opline = (size_t)watch->addr.ptr - 1; } return 1; @@ -250,37 +159,14 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { } void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { - phpdbg_btree **branch = &PHPDBG_G(watchpoint_tree); - int i = sizeof(void *) * 8 - 1; - - do { - if (*branch == NULL) { - break; - } - branch = &(*branch)->branches[((size_t)watch->addr.ptr >> i) % 2]; - } while (i--); - - if (*branch == NULL) { - phpdbg_btree *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree)); - do { - (*branch)->branches[!(((size_t)watch->addr.ptr >> i) % 2)] = NULL; - branch = &(*branch)->branches[((size_t)watch->addr.ptr >> i) % 2]; - *branch = ++memory; - } while (i--); - } - - (*branch)->watchpoint = watch; + phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); } -void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { +void phpdbg_activate_watchpoint (phpdbg_watchpoint_t *watch) { int m; - watch->addr.ptr = addr; - watch->size = size; - watch->type = WATCH_ON_PTR; - /* pagesize is assumed to be in the range of 2^x */ - m = mprotect(phpdbg_get_page_boundary(addr), phpdbg_get_total_page_size(addr, size), PROT_NONE | PROT_READ); + m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), PROT_NONE | PROT_READ); if (m == FAILURE) { phpdbg_error("Unable to set watchpoint (mprotect() failed)"); @@ -288,6 +174,12 @@ void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t } } +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { + watch->addr.ptr = addr; + watch->size = size; + watch->type = WATCH_ON_PTR; +} + void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); watch->type = WATCH_ON_ZVAL; @@ -315,9 +207,11 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { /* Lookup current symbol table */ if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { + phpdbg_create_zval_watchpoint(*zv, watch); zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); phpdbg_store_watchpoint(watch TSRMLS_CC); - phpdbg_create_zval_watchpoint(*zv, watch); + + phpdbg_activate_watchpoint(watch); return SUCCESS; } From a7b0dfb7b12cdfb6cd78e5f1c686094d7a567555 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 15 Dec 2013 09:15:34 -0500 Subject: [PATCH 008/137] Preventing possible segfault --- phpdbg_btree.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpdbg_btree.c b/phpdbg_btree.c index f47422f4630..21f3fedcbb1 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -34,6 +34,10 @@ phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx) { phpdbg_btree_branch *branch = tree->branch; int i = tree->depth - 1; + if (branch == NULL) { + return NULL; + } + do { if ((idx >> i) % 2 == 1) { if (branch->branches[1]) { From 0a8c20e740d6680ecfe566e5e681a3da4c67970e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 16 Dec 2013 10:29:31 -0500 Subject: [PATCH 009/137] Handle automatic removing of watchpoints and cleanup at the end --- phpdbg.c | 5 +- phpdbg_watch.c | 211 +++++++++++++++++++++++++++++-------------------- phpdbg_watch.h | 4 + 3 files changed, 131 insertions(+), 89 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 7c80b591e36..e3c998dda5b 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -154,7 +154,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0); - zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, NULL, 0); /* TODO: dtor */ + phpdbg_setup_watchpoints(TSRMLS_C); zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0); zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0); @@ -176,6 +176,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); zend_hash_destroy(&PHPDBG_G(seek)); zend_hash_destroy(&PHPDBG_G(registered)); + zend_hash_destroy(&PHPDBG_G(watchpoints)); if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); @@ -853,8 +854,6 @@ int main(int argc, char **argv) /* {{{ */ tsrm_ls = ts_resource(0); #endif - phpdbg_setup_watchpoints(TSRMLS_C); - phpdbg_main: if (!cleaning) { bp_tmp_file = malloc(L_tmpnam); diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 0f3e1322cff..a87da5fecab 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -38,31 +38,6 @@ typedef struct { #define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) -static void phpdbg_watch_mem_dtor(void *llist_data) { - void *page = (*(phpdbg_watch_memdump **)llist_data)->page; - size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; - - efree(*(void **)llist_data); - - /* Disble writing again */ - mprotect(page, size, PROT_NONE | PROT_READ); -} - -void phpdbg_setup_watchpoints(TSRMLS_D) { -#ifdef _SC_PAGE_SIZE - phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); -#endif -#ifdef _SC_PAGESIZE - phpdbg_pagesize = sysconf(_SC_PAGESIZE); -#endif -#ifdef _SC_NUTC_OS_PAGESIZE - phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); -#endif - - zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); - phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); -} - static inline void *phpdbg_get_page_boundary(void *addr) { return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); } @@ -83,6 +58,77 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) { return watch; } +static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); +} + +static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access) { + int m; + + /* pagesize is assumed to be in the range of 2^x */ + m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access); + + if (m == FAILURE) { + phpdbg_error("Unable to (un)set watchpoint (mprotect() failed)"); + zend_bailout(); + } +} + +static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch) { + phpdbg_change_watchpoint_access(watch, PROT_READ); +} + +static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch) { + phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE); +} + +void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { + watch->addr.ptr = addr; + watch->size = size; + watch->type = WATCH_ON_PTR; +} + +void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { + phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); + watch->type = WATCH_ON_ZVAL; +} + +int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { + zval **zv; + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + + if (!EG(active_op_array)) { + phpdbg_error("No active op array!"); + return SUCCESS; + } + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + + if (!EG(active_symbol_table)) { + phpdbg_error("No active symbol table!"); + return SUCCESS; + } + } + + watch->str = estrndup(name, len); + watch->parent_container = EG(current_execute_data)->symbol_table; + watch->name_in_parent = estrndup(name, len); + watch->name_in_parent_len = len + 1; + + /* Lookup current symbol table */ + if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { + phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + phpdbg_store_watchpoint(watch TSRMLS_CC); + + phpdbg_activate_watchpoint(watch); + return SUCCESS; + } + + return FAILURE; +} + int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { void *addr; void *page; @@ -115,6 +161,50 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) return SUCCESS; } +void phpdbg_watchpoints_clean(TSRMLS_DC) { + zend_hash_clean(&PHPDBG_G(watchpoints)); +} + +static void phpdbg_watch_dtor(void *pDest) { + TSRMLS_FETCH(); + + phpdbg_watchpoint_t *watch = (phpdbg_watchpoint_t *)pDest; + + phpdbg_deactivate_watchpoint(watch); + phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); + + efree(watch->str); + efree(watch->name_in_parent); + + efree(watch); +} + +static void phpdbg_watch_mem_dtor(void *llist_data) { + void *page = (*(phpdbg_watch_memdump **)llist_data)->page; + size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; + + efree(*(void **)llist_data); + + /* Disble writing again */ + mprotect(page, size, PROT_NONE | PROT_READ); +} + +void phpdbg_setup_watchpoints(TSRMLS_D) { +#ifdef _SC_PAGE_SIZE + phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); +#endif +#ifdef _SC_PAGESIZE + phpdbg_pagesize = sysconf(_SC_PAGESIZE); +#endif +#ifdef _SC_NUTC_OS_PAGESIZE + phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); +#endif + + zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); + phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); + _zend_hash_init(&PHPDBG_G(watchpoints), 8, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC); +} + static int phpdbg_print_changed_zval(void *llist_data) { TSRMLS_FETCH(); @@ -133,12 +223,21 @@ static int phpdbg_print_changed_zval(void *llist_data) { phpdbg_notice("Breaking on watchpoint %s", watch->str); switch (watch->type) { case WATCH_ON_ZVAL: + phpdbg_write("Old value: "); zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); + + /* check if zval was removed */ + if (((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_hash_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len)) { + phpdbg_notice("Watchpoint %s was unset, removing watchpoint"); + phpdbg_deactivate_watchpoint(watch); + break; + } + phpdbg_write("New value: "); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); - phpdbg_writeln("\nNew refcount: %d; Old is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); break; } } @@ -157,63 +256,3 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; } - -static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { - phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); -} - -static void phpdbg_activate_watchpoint (phpdbg_watchpoint_t *watch) { - int m; - - /* pagesize is assumed to be in the range of 2^x */ - m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), PROT_NONE | PROT_READ); - - if (m == FAILURE) { - phpdbg_error("Unable to set watchpoint (mprotect() failed)"); - zend_bailout(); - } -} - -void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { - watch->addr.ptr = addr; - watch->size = size; - watch->type = WATCH_ON_PTR; -} - -void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { - phpdbg_create_addr_watchpoint(zv, sizeof(zval), watch); - watch->type = WATCH_ON_ZVAL; -} - -int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { - zval **zv; - phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); - - if (!EG(active_op_array)) { - phpdbg_error("No active op array!"); - return SUCCESS; - } - - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - - if (!EG(active_symbol_table)) { - phpdbg_error("No active symbol table!"); - return SUCCESS; - } - } - - watch->str = estrndup(name, len); - - /* Lookup current symbol table */ - if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); - zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_store_watchpoint(watch TSRMLS_CC); - - phpdbg_activate_watchpoint(watch); - return SUCCESS; - } - - return FAILURE; -} diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 272e613ad25..8c8336312b1 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -44,10 +44,14 @@ typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; struct _phpdbg_watchpoint_t { phpdbg_watchpoint_t *parent; + HashTable *parent_container; + char *name_in_parent; + size_t name_in_parent_len; char *str; union { zval *zv; HashTable *ht; + zend_llist *llist; void *ptr; } addr; size_t size; From 0dbc5c2087622f203143bbf4347aff0eeb0e4e0b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 18 Dec 2013 02:56:20 -0500 Subject: [PATCH 010/137] first working version of wildcard watchpoints --- phpdbg.c | 1 + phpdbg_prompt.c | 4 ++ phpdbg_watch.c | 141 ++++++++++++++++++++++++++++++++++++++++-------- phpdbg_watch.h | 4 +- test.php | 13 +++++ 5 files changed, 141 insertions(+), 22 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index e3c998dda5b..891875ef85c 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -177,6 +177,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(seek)); zend_hash_destroy(&PHPDBG_G(registered)); zend_hash_destroy(&PHPDBG_G(watchpoints)); + zend_llist_destroy(&PHPDBG_G(watchlist_mem)); if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 626177fa4ea..1caa219ffe3 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1020,6 +1020,10 @@ PHPDBG_COMMAND(watch) /* {{{ */ phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC); break; + case EMPTY_PARAM: + phpdbg_list_watchpoints(TSRMLS_C); + break; + phpdbg_default_switch_case(); } diff --git a/phpdbg_watch.c b/phpdbg_watch.c index a87da5fecab..b3438c6edf6 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -93,10 +93,113 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_ZVAL; } -int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i TSRMLS_DC) { + zend_bool new_index = 1; + char *last_index; + int index_len = 0; zval **zv; - phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + if (len < 2 || *input != '$') { + goto error; + } + + while (i++ < len) { + if (i == len) { + new_index = 1; + } else { + switch (input[i]) { + case '[': + new_index = 1; + break; + case ']': + break; + case '>': + if (last_index[index_len - 1] == '-') { + new_index = 1; + index_len--; + } + break; + + default: + if (new_index) { + last_index = input + i; + new_index = 0; + } + if (input[i - 1] == ']') { + goto error; + } + index_len++; + } + } + + if (new_index && index_len == 0) { + HashPosition position; + for (zend_hash_internal_pointer_reset_ex(parent, &position); + zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(parent, &position)) { + if (i == len || (i == len - 1 && input[len - 1] == ']')) { + zval *key = emalloc(sizeof(zval)); + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + zend_hash_get_current_key_zval_ex(parent, key, &position); + convert_to_string(key); + watch->str_len = asprintf(&watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); + efree(key); + watch->name_in_parent = estrndup(last_index, index_len); + watch->name_in_parent_len = index_len; + watch->parent_container = parent; + phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_store_watchpoint(watch TSRMLS_CC); + zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + + phpdbg_activate_watchpoint(watch); + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i TSRMLS_CC); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i TSRMLS_CC); + } else { + /* Ignore silently */ + } + } + return SUCCESS; + } else if (new_index) { + char last_chr = last_index[index_len]; + last_index[index_len] = 0; + if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { + phpdbg_error("%.*s is undefined", i, input); + return FAILURE; + } + last_index[index_len] = last_chr; + if (i == len) { + phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + watch->str = estrndup(input, len); + watch->str_len = len; + watch->name_in_parent = estrndup(last_index, index_len); + watch->name_in_parent_len = index_len; + watch->parent_container = parent; + phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_store_watchpoint(watch TSRMLS_CC); + zend_hash_add(&PHPDBG_G(watchpoints), input, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + + phpdbg_activate_watchpoint(watch); + } else if (Z_TYPE_PP(zv) == IS_OBJECT) { + parent = Z_OBJPROP_PP(zv); + } else if (Z_TYPE_PP(zv) == IS_ARRAY) { + parent = Z_ARRVAL_PP(zv); + } else { + phpdbg_error("%.*s is nor an array nor an object", i, input); + return FAILURE; + } + index_len = 0; + } + } + + return SUCCESS; + error: + phpdbg_error("Malformed input"); + return FAILURE; +} + +int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (!EG(active_op_array)) { phpdbg_error("No active op array!"); return SUCCESS; @@ -111,22 +214,7 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC) { } } - watch->str = estrndup(name, len); - watch->parent_container = EG(current_execute_data)->symbol_table; - watch->name_in_parent = estrndup(name, len); - watch->name_in_parent_len = len + 1; - - /* Lookup current symbol table */ - if (zend_hash_find(EG(current_execute_data)->symbol_table, name, len + 1, (void **)&zv) == SUCCESS) { - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); - zend_hash_add(&PHPDBG_G(watchpoints), name, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_store_watchpoint(watch TSRMLS_CC); - - phpdbg_activate_watchpoint(watch); - return SUCCESS; - } - - return FAILURE; + return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0 TSRMLS_CC); } int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { @@ -229,9 +317,9 @@ static int phpdbg_print_changed_zval(void *llist_data) { phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); /* check if zval was removed */ - if (((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_hash_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len)) { - phpdbg_notice("Watchpoint %s was unset, removing watchpoint"); - phpdbg_deactivate_watchpoint(watch); + if (((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1)) { + phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); break; } @@ -256,3 +344,14 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; } + +void phpdbg_list_watchpoints(TSRMLS_D) { + HashPosition position; + phpdbg_watchpoint_t **watch; + + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position); + zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(watchpoints), &position)) { + phpdbg_writeln("%.*s", (int)(*watch)->str_len, (*watch)->str); + } +} diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 8c8336312b1..ce76321056b 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -48,10 +48,10 @@ struct _phpdbg_watchpoint_t { char *name_in_parent; size_t name_in_parent_len; char *str; + size_t str_len; union { zval *zv; HashTable *ht; - zend_llist *llist; void *ptr; } addr; size_t size; @@ -68,4 +68,6 @@ int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC); int phpdbg_print_changed_zvals(TSRMLS_D); +void phpdbg_list_watchpoints(TSRMLS_D); + #endif diff --git a/test.php b/test.php index 744ed798650..669eb347404 100644 --- a/test.php +++ b/test.php @@ -50,5 +50,18 @@ function phpdbg_test_ob() echo $b; } +$array = [ + 1, + 2, + [3, 4], + [5, 6], +]; + +array_walk($array, function (&$item) { + if (is_array($item)) + $item[0] += 2; + else + $item -= 1; +}); ?> From 5e351695b6d4ca14c5af7e2690c38c7c07444640 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 19 Dec 2013 11:05:38 -0500 Subject: [PATCH 011/137] Added deleting of watchpoints --- phpdbg_prompt.c | 8 +++--- phpdbg_utils.c | 18 +++++++++++++ phpdbg_utils.h | 2 ++ phpdbg_watch.c | 68 ++++++++++++++++++++++++++++++++++--------------- phpdbg_watch.h | 17 ++++++++++--- 5 files changed, 85 insertions(+), 28 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 1caa219ffe3..ae77d4065f6 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -51,11 +51,11 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1), PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, 1), - PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2), - PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1), + PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2), + PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1), PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0), PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), - PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 2), + PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 2), PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1), PHPDBG_COMMAND_D(aliases, "show alias list", 'a', NULL, 0), PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, 1), @@ -63,7 +63,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 1), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), - PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', NULL, 0), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, 1), PHPDBG_END_COMMAND }; /* }}} */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 47437f223e4..cb48c4e78bc 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -377,3 +377,21 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ return PHPDBG_G(prompt)[1]; } /* }}} */ + +int phpdbg_rebuild_symtable(TSRMLS_D) { + if (!EG(active_op_array)) { + phpdbg_error("No active op array!"); + return FAILURE; + } + + if (!EG(active_symbol_table)) { + zend_rebuild_symbol_table(TSRMLS_C); + + if (!EG(active_symbol_table)) { + phpdbg_error("No active symbol table!"); + return FAILURE; + } + } + + return SUCCESS; +} diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 3126d0c2cf6..b79c203a2e9 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -106,4 +106,6 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); /* }}} */ PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC); PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */ +int phpdbg_rebuild_symtable(TSRMLS_D); + #endif /* PHPDBG_UTILS_H */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index b3438c6edf6..5df867a2b45 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -22,6 +22,7 @@ #include "phpdbg.h" #include "phpdbg_btree.h" #include "phpdbg_watch.h" +#include "phpdbg_utils.h" #include #include @@ -93,7 +94,25 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_ZVAL; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i TSRMLS_DC) { +static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch) { + phpdbg_store_watchpoint(watch TSRMLS_CC); + zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + + phpdbg_activate_watchpoint(watch); + + return SUCCESS; +} + +static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch) { + int ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + + efree(watch); + + return ret; +} + +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t *) TSRMLS_DC) { + int ret = FAILURE; zend_bool new_index = 1; char *last_index; int index_len = 0; @@ -148,19 +167,17 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent_len = index_len; watch->parent_container = parent; phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); - phpdbg_store_watchpoint(watch TSRMLS_CC); - zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_activate_watchpoint(watch); + ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { - phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i TSRMLS_CC); + phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback TSRMLS_CC); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { - phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i TSRMLS_CC); + phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback TSRMLS_CC); } else { /* Ignore silently */ } } - return SUCCESS; + return ret; } else if (new_index) { char last_chr = last_index[index_len]; last_index[index_len] = 0; @@ -177,10 +194,8 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent_len = index_len; watch->parent_container = parent; phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); - phpdbg_store_watchpoint(watch TSRMLS_CC); - zend_hash_add(&PHPDBG_G(watchpoints), input, len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_activate_watchpoint(watch); + ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { parent = Z_OBJPROP_PP(zv); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -193,28 +208,41 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par } } - return SUCCESS; + return ret; error: phpdbg_error("Malformed input"); return FAILURE; } +PHPDBG_WATCH(delete) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + if (phpdbg_delete_var_watchpoint(param->str, param->len TSRMLS_CC) == FAILURE) { + phpdbg_error("Nothing was deleted, no corresponding watchpoint found"); + } + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { - if (!EG(active_op_array)) { - phpdbg_error("No active op array!"); + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { return SUCCESS; } - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); + return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_create_watchpoint TSRMLS_CC); +} - if (!EG(active_symbol_table)) { - phpdbg_error("No active symbol table!"); - return SUCCESS; - } +int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return SUCCESS; } - return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0 TSRMLS_CC); + return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_delete_watchpoint TSRMLS_CC); } int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { diff --git a/phpdbg_watch.h b/phpdbg_watch.h index ce76321056b..0f96828edf3 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -27,10 +27,17 @@ #define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name) /** -* Printer Forward Declarations -*/ -/*PHPDBG_WATCH();*/ + * Printer Forward Declarations + */ +PHPDBG_WATCH(delete); +/** + * Commands + */ + +static const phpdbg_command_t phpdbg_watch_commands[] = { + PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, 1), +}; /* Watchpoint functions/typedefs */ @@ -64,7 +71,9 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch); void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch); -int phpdbg_create_var_watchpoint(char *name, size_t len TSRMLS_DC); + +int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC); +int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC); int phpdbg_print_changed_zvals(TSRMLS_D); From 3f70e9f8bd6e8f7fee4aec65bfb88d81b810c4ea Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 19 Dec 2013 22:21:08 -0500 Subject: [PATCH 012/137] Fixed deletion of watchpoints --- phpdbg_btree.c | 14 ++++++++++---- phpdbg_watch.c | 14 +++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/phpdbg_btree.c b/phpdbg_btree.c index 21f3fedcbb1..6b70d1453d7 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -184,18 +184,24 @@ int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx) { } while (i--); if (i_last_dual_branch == -1) { - efree(tree); - tree = NULL; + efree(tree->branch); + tree->branch = NULL; } else { if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) { memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], i_last_dual_branch * sizeof(phpdbg_btree_branch)); - efree(last_dual_branch->branches[last_dual_branch_branch]); + efree(last_dual_branch->branches[!last_dual_branch_branch]); last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1; + + branch = last_dual_branch->branches[!last_dual_branch_branch]; + for (i = i_last_dual_branch; i--;) { + branch->branches[!!branch->branches[1]] = last_dual_branch + i_last_dual_branch - i + 1; + branch = branch->branches[!!branch->branches[1]]; + } } else { efree(last_dual_branch->branches[last_dual_branch_branch]); } - last_dual_branch->branches[i_last_dual_branch] = NULL; + last_dual_branch->branches[last_dual_branch_branch] = NULL; } return SUCCESS; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 5df867a2b45..0c5eab1005c 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -48,7 +48,14 @@ static inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { } static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) { - phpdbg_watchpoint_t *watch = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1)->ptr; + phpdbg_watchpoint_t *watch; + phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1); + + if (result == NULL) { + return NULL; + } + + watch = result->ptr; /* check if that addr is in a mprotect()'ed memory area */ if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) { @@ -161,7 +168,8 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); zend_hash_get_current_key_zval_ex(parent, key, &position); convert_to_string(key); - watch->str_len = asprintf(&watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); + watch->str = emalloc(i + Z_STRLEN_P(key) + 2); + watch->str_len = sprintf(watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); efree(key); watch->name_in_parent = estrndup(last_index, index_len); watch->name_in_parent_len = index_len; @@ -284,7 +292,7 @@ void phpdbg_watchpoints_clean(TSRMLS_DC) { static void phpdbg_watch_dtor(void *pDest) { TSRMLS_FETCH(); - phpdbg_watchpoint_t *watch = (phpdbg_watchpoint_t *)pDest; + phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest; phpdbg_deactivate_watchpoint(watch); phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); From e2172ba39c3b00c82eb3b6ca3e4cde8df722a086 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 20 Dec 2013 22:10:03 -0500 Subject: [PATCH 013/137] ZTS fixed --- phpdbg_watch.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 0c5eab1005c..37112b555e2 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -70,7 +70,7 @@ static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); } -static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access) { +static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) { int m; /* pagesize is assumed to be in the range of 2^x */ @@ -82,12 +82,12 @@ static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int acce } } -static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch) { - phpdbg_change_watchpoint_access(watch, PROT_READ); +static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ TSRMLS_CC); } -static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch) { - phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE); +static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE TSRMLS_CC); } void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { @@ -101,16 +101,16 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_ZVAL; } -static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch) { +static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_store_watchpoint(watch TSRMLS_CC); zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_activate_watchpoint(watch); + phpdbg_activate_watchpoint(watch TSRMLS_CC); return SUCCESS; } -static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch) { +static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { int ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); efree(watch); @@ -118,7 +118,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch) { return ret; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t *) TSRMLS_DC) { +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { int ret = FAILURE; zend_bool new_index = 1; char *last_index; @@ -174,9 +174,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent = estrndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_create_zval_watchpoint(*zv, watch); - ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback TSRMLS_CC); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -201,9 +201,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent = estrndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_create_zval_watchpoint(*zv, watch); - ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { parent = Z_OBJPROP_PP(zv); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -294,7 +294,7 @@ static void phpdbg_watch_dtor(void *pDest) { phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest; - phpdbg_deactivate_watchpoint(watch); + phpdbg_deactivate_watchpoint(watch TSRMLS_CC); phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); efree(watch->str); From 6ee1da1f55ea630240af108d9c570e8f790acfd2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 20 Dec 2013 22:17:30 -0500 Subject: [PATCH 014/137] ZTS fixed --- phpdbg_watch.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 0c5eab1005c..a506f38486b 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -70,7 +70,7 @@ static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); } -static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access) { +static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) { int m; /* pagesize is assumed to be in the range of 2^x */ @@ -82,12 +82,12 @@ static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int acce } } -static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch) { - phpdbg_change_watchpoint_access(watch, PROT_READ); +static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ TSRMLS_CC); } -static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch) { - phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE); +static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE TSRMLS_CC); } void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { @@ -101,16 +101,16 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_ZVAL; } -static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch) { +static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_store_watchpoint(watch TSRMLS_CC); zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); - phpdbg_activate_watchpoint(watch); + phpdbg_activate_watchpoint(watch TSRMLS_CC); return SUCCESS; } -static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch) { +static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { int ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); efree(watch); @@ -118,7 +118,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch) { return ret; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t *) TSRMLS_DC) { +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { int ret = FAILURE; zend_bool new_index = 1; char *last_index; @@ -174,9 +174,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent = estrndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_create_zval_watchpoint(*zv, watch); - ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback TSRMLS_CC); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -201,9 +201,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par watch->name_in_parent = estrndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; - phpdbg_create_zval_watchpoint(*zv, watch TSRMLS_CC); + phpdbg_create_zval_watchpoint(*zv, watch); - ret = callback(watch) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; + ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { parent = Z_OBJPROP_PP(zv); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { @@ -285,7 +285,7 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) return SUCCESS; } -void phpdbg_watchpoints_clean(TSRMLS_DC) { +void phpdbg_watchpoints_clean(TSRMLS_D) { zend_hash_clean(&PHPDBG_G(watchpoints)); } @@ -294,7 +294,7 @@ static void phpdbg_watch_dtor(void *pDest) { phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest; - phpdbg_deactivate_watchpoint(watch); + phpdbg_deactivate_watchpoint(watch TSRMLS_CC); phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); efree(watch->str); From 433bc142a6bb8094c331cb946c15444adaa6932b Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 23 Dec 2013 21:51:00 +0000 Subject: [PATCH 015/137] credits file --- CREDITS | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CREDITS diff --git a/CREDITS b/CREDITS new file mode 100644 index 00000000000..3a26c576b6f --- /dev/null +++ b/CREDITS @@ -0,0 +1,4 @@ +phpdbg +Felipe Pena +Joe Watkins +Bob Weinand From f4eeda9a9b581bece77757a5688d0b34a42fd336 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 31 Dec 2013 13:14:36 -0500 Subject: [PATCH 016/137] First try of recursive watchpoints --- phpdbg_watch.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_watch.h | 4 ++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index a506f38486b..f6d8646a1f0 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -110,6 +110,58 @@ static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { return SUCCESS; } +static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + HashTable *ht; + + if (watch->type != WATCH_ON_ZVAL) { + return FAILURE; + } + + phpdbg_create_watchpoint(watch TSRMLS_CC); + + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + default: + return SUCCESS; + } + + { + HashPosition position; + zval **zv; + zval key; + for (zend_hash_internal_pointer_reset_ex(ht, &position); + zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(ht, &position)) { + phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); + + new_watch->parent = watch; + new_watch->parent_container = ht; + + zend_hash_get_current_key_zval_ex(ht, &key, &position); + if (Z_TYPE(key) == IS_STRING) { + new_watch->name_in_parent = Z_STRVAL(key); + new_watch->name_in_parent_len = Z_STRLEN(key); + } else { + new_watch->name_in_parent = NULL; + new_watch->name_in_parent_len = asprintf(&new_watch->name_in_parent, "%ld", Z_LVAL(key)); + } + + new_watch->str = NULL; + new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + + phpdbg_create_zval_watchpoint(*zv, new_watch); + phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); + } + } + + return SUCCESS; +} + static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { int ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); @@ -237,6 +289,23 @@ PHPDBG_WATCH(delete) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_WATCH(recursive) /* {{{ */ +{ + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return SUCCESS; + } + + switch (param->type) { + case STR_PARAM: + phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_recursive_watchpoint TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { return SUCCESS; diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 0f96828edf3..411349816be 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -30,13 +30,15 @@ * Printer Forward Declarations */ PHPDBG_WATCH(delete); +PHPDBG_WATCH(recursive); /** * Commands */ static const phpdbg_command_t phpdbg_watch_commands[] = { - PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, 1), + PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, 1), + PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, 1), }; /* Watchpoint functions/typedefs */ From 78e274af31e33078090ee29007960a9e169058e4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 10 Jan 2014 13:54:07 -0500 Subject: [PATCH 017/137] Added rudimentary support for watchpoints on an array itself --- phpdbg.c | 18 +++++++++ phpdbg.h | 1 + phpdbg_btree.c | 11 +++-- phpdbg_watch.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++-- phpdbg_watch.h | 8 +++- 5 files changed, 136 insertions(+), 9 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 4955d2e1bf3..54710fad773 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -28,6 +28,15 @@ #include "phpdbg_list.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "zend_alloc.h" + +/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c */ +struct _zend_mm_heap { + int use_zend_alloc; + void *(*_malloc)(size_t); + void (*_free)(void*); + void *(*_realloc)(void*, size_t); +}; /* {{{ remote console headers */ #ifndef _WIN32 @@ -1144,6 +1153,15 @@ phpdbg_main: if (phpdbg->startup(phpdbg) == SUCCESS) { + zend_mm_heap *mm_heap = zend_mm_set_heap(NULL TSRMLS_CC); + if (!mm_heap->use_zend_alloc) { + free(mm_heap); + mm_heap = zend_mm_startup(); + } + PHPDBG_G(original_free_function) = mm_heap->_free; + mm_heap->_free = phpdbg_watch_efree; + zend_mm_set_heap(mm_heap TSRMLS_CC); + zend_activate(TSRMLS_C); #ifdef ZEND_SIGNALS diff --git a/phpdbg.h b/phpdbg.h index 63cdd352b7d..79f98fd2f79 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -175,6 +175,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable watchpoints; /* watchpoints */ zend_llist watchlist_mem; /* triggered watchpoints */ zend_bool watchpoint_hit; /* a watchpoint was hit */ + void (*original_free_function)(void *); /* the original AG(mm_heap)->_free function */ char *exec; /* file to execute */ size_t exec_len; /* size of exec */ diff --git a/phpdbg_btree.c b/phpdbg_btree.c index 6b70d1453d7..f3b86dd91fc 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -166,21 +166,24 @@ int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, } int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx) { - int i = tree->depth - 1; + int i = tree->depth; phpdbg_btree_branch *branch = tree->branch; int i_last_dual_branch = -1, last_dual_branch_branch; phpdbg_btree_branch *last_dual_branch = NULL; + goto check_branch_existence; do { - if (branch == NULL) { - return FAILURE; - } if (branch->branches[0] && branch->branches[1]) { last_dual_branch = branch; i_last_dual_branch = i; last_dual_branch_branch = (idx >> i) % 2; } branch = branch->branches[(idx >> i) % 2]; + +check_branch_existence: + if (branch == NULL) { + return FAILURE; + } } while (i--); if (i_last_dual_branch == -1) { diff --git a/phpdbg_watch.c b/phpdbg_watch.c index f6d8646a1f0..a0b9d19dcc8 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -101,6 +101,11 @@ void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_ZVAL; } +void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) { + phpdbg_create_addr_watchpoint(ht, sizeof(HashTable), watch); + watch->type = WATCH_ON_HASHTABLE; +} + static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { phpdbg_store_watchpoint(watch TSRMLS_CC); zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); @@ -110,6 +115,27 @@ static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { return SUCCESS; } +static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + HashTable *ht; + + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + default: + return FAILURE; + } + + phpdbg_create_ht_watchpoint(Z_ARRVAL_P(watch->addr.zv), watch); + + phpdbg_create_watchpoint(watch TSRMLS_CC); + + return SUCCESS; +} + static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { HashTable *ht; @@ -134,6 +160,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ HashPosition position; zval **zv; zval key; + for (zend_hash_internal_pointer_reset_ex(ht, &position); zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS; zend_hash_move_forward_ex(ht, &position)) { @@ -159,6 +186,20 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ } } + { + phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); + + new_watch->parent = watch; + new_watch->parent_container = ht; + new_watch->name_in_parent = watch->name_in_parent; + new_watch->name_in_parent_len = watch->name_in_parent_len; + new_watch->str = watch->str; + new_watch->str_len = watch->str_len; + + phpdbg_create_ht_watchpoint(ht, new_watch); + phpdbg_create_watchpoint(new_watch TSRMLS_CC); + } + return SUCCESS; } @@ -306,6 +347,23 @@ PHPDBG_WATCH(recursive) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_WATCH(array) /* {{{ */ +{ + if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { + return SUCCESS; + } + + switch (param->type) { + case STR_PARAM: + phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_array_watchpoint TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { return SUCCESS; @@ -404,11 +462,11 @@ static int phpdbg_print_changed_zval(void *llist_data) { phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; /* fetch all changes between dump->page and dump->page + dump->size */ phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); - phpdbg_btree_result *result; - + phpdbg_btree_result *result, *htresult; + int elementDiff; while ((result = phpdbg_btree_next(&pos))) { - phpdbg_watchpoint_t *watch = result->ptr; + phpdbg_watchpoint_t *watch = result->ptr, *htwatch; void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { PHPDBG_G(watchpoint_hit) = 1; @@ -425,12 +483,40 @@ static int phpdbg_print_changed_zval(void *llist_data) { if (((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1)) { phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + + if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY) { + goto remove_ht_watch; + } + break; } phpdbg_write("New value: "); zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + + if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) { +remove_ht_watch: + htwatch = htresult->ptr; + zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len); + } + + break; + + case WATCH_ON_HASHTABLE: + + elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); + if (elementDiff) { + if (elementDiff < 0) { + phpdbg_writeln("%d elements were removed from the array", -elementDiff); + } else { + phpdbg_writeln("%d elements were added to the array", elementDiff); + /* TODO: add, if recursive watchpoint, the new elements to the elements to watch */ + } + } + if (((HashTable *)oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) { + phpdbg_writeln("Internal pointer of array was changed"); + } break; } } @@ -460,3 +546,18 @@ void phpdbg_list_watchpoints(TSRMLS_D) { phpdbg_writeln("%.*s", (int)(*watch)->str_len, (*watch)->str); } } + +void phpdbg_watch_efree(void *ptr) { + TSRMLS_FETCH(); + phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr); + + if (result) { + phpdbg_watchpoint_t *watch = result->ptr; + + if (watch->addr.ptr + watch->size > ptr) { + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + } + + PHPDBG_G(original_free_function)(ptr); +} diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 411349816be..8e530875848 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -29,6 +29,7 @@ /** * Printer Forward Declarations */ +PHPDBG_WATCH(array); PHPDBG_WATCH(delete); PHPDBG_WATCH(recursive); @@ -37,8 +38,9 @@ PHPDBG_WATCH(recursive); */ static const phpdbg_command_t phpdbg_watch_commands[] = { - PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, 1), - PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, 1), + PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, 1), + PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, 1), + PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, 1), }; /* Watchpoint functions/typedefs */ @@ -81,4 +83,6 @@ int phpdbg_print_changed_zvals(TSRMLS_D); void phpdbg_list_watchpoints(TSRMLS_D); +void phpdbg_watch_efree(void *ptr); + #endif From f4a7e50156fd494e16e9d434a63b628d060da73f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 17 Jan 2014 23:09:07 +0100 Subject: [PATCH 018/137] Update year --- phpdbg.c | 7 +++---- phpdbg.h | 2 +- phpdbg_bp.c | 2 +- phpdbg_bp.h | 2 +- phpdbg_break.c | 2 +- phpdbg_break.h | 2 +- phpdbg_cmd.c | 2 +- phpdbg_cmd.h | 2 +- phpdbg_frame.c | 2 +- phpdbg_frame.h | 2 +- phpdbg_help.c | 2 +- phpdbg_help.h | 2 +- phpdbg_info.c | 2 +- phpdbg_info.h | 2 +- phpdbg_list.c | 2 +- phpdbg_list.h | 2 +- phpdbg_opcode.c | 2 +- phpdbg_opcode.h | 2 +- phpdbg_print.c | 2 +- phpdbg_print.h | 2 +- phpdbg_prompt.c | 2 +- phpdbg_prompt.h | 2 +- phpdbg_set.c | 2 +- phpdbg_set.h | 2 +- phpdbg_utils.c | 2 +- phpdbg_utils.h | 2 +- 26 files changed, 28 insertions(+), 29 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index a2e1e75b233..e7f841c0bca 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -137,9 +137,8 @@ static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */ static void php_phpdbg_destroy_registered(void *data) /* {{{ */ { - TSRMLS_FETCH(); - zend_function *function = (zend_function*) data; + TSRMLS_FETCH(); destroy_zend_function( function TSRMLS_CC); @@ -1041,7 +1040,7 @@ phpdbg_main: sapi_startup(phpdbg); phpdbg->startup(phpdbg); printf( - "phpdbg %s (built: %s %s)\nPHP %s, Copyright (c) 1997-2013 The PHP Group\n%s", + "phpdbg %s (built: %s %s)\nPHP %s, Copyright (c) 1997-2014 The PHP Group\n%s", PHPDBG_VERSION, __DATE__, __TIME__, diff --git a/phpdbg.h b/phpdbg.h index 7844772533b..6b7afb23704 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 69e0fa7086d..511d1db57d7 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_bp.h b/phpdbg_bp.h index ed1b413f6d3..b1a9ddf4749 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_break.c b/phpdbg_break.c index 1423b960e66..f56f76facd9 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_break.h b/phpdbg_break.h index 04abeb6805f..f90e351d6de 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index c24f08d6b1b..29424d00fe7 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index e779fd4b55d..c86f92bb478 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 24aff59dd92..de02addc1b9 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_frame.h b/phpdbg_frame.h index fbccd5404f5..7c4574ed280 100644 --- a/phpdbg_frame.h +++ b/phpdbg_frame.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_help.c b/phpdbg_help.c index edb12659554..a02cb41c143 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_help.h b/phpdbg_help.h index 012a1b49e73..319142cb5b2 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_info.c b/phpdbg_info.c index 1744f59215b..0f4233bf30c 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_info.h b/phpdbg_info.h index 5d538123707..a6b4e3719fe 100644 --- a/phpdbg_info.h +++ b/phpdbg_info.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_list.c b/phpdbg_list.c index b49be857efa..eb1091550b0 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_list.h b/phpdbg_list.h index d6180271585..f9d1885eaf2 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 81191584696..50073eb22bb 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_opcode.h b/phpdbg_opcode.h index 5771488e707..144442981dd 100644 --- a/phpdbg_opcode.h +++ b/phpdbg_opcode.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_print.c b/phpdbg_print.c index 51edcfbf8da..c4925fe5fd7 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_print.h b/phpdbg_print.h index 1232f544d29..80010d5e7cc 100644 --- a/phpdbg_print.h +++ b/phpdbg_print.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6d199b06731..cb46407957c 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index e6706c7d5b1..6807d88f41d 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_set.c b/phpdbg_set.c index 2472e1868c0..7c4da12a46e 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_set.h b/phpdbg_set.h index 1c48786c66c..120aeb34f4e 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 7b2000da0ea..1effcfccaf9 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | diff --git a/phpdbg_utils.h b/phpdbg_utils.h index fbc17b78dd3..c5164c3ac31 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | From a1f592565254a991efe80a3f910733fbb29813fc Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 18 Jan 2014 13:18:28 -0500 Subject: [PATCH 019/137] Fixed that for example "run" is only set as last cmd after the whole execution --- phpdbg_cmd.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 9f052d6f6f3..21e07c88dfb 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -582,6 +582,8 @@ PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *in (command->alias == *input->argv[0]->string))) { phpdbg_param_t param; + phpdbg_command_t *initial_last_cmd; + phpdbg_param_t initial_last_param; param.type = EMPTY_PARAM; @@ -644,15 +646,20 @@ PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *in } } + PHPDBG_G(lparam) = param; + initial_last_param = PHPDBG_G(lparam); + initial_last_cmd = (phpdbg_command_t *)PHPDBG_G(lcmd); + PHPDBG_G(lcmd) = (phpdbg_command_t *)command; + rc = command->handler(¶m, input TSRMLS_CC); /* only set last command when it is worth it! */ - if ((rc != FAILURE) && - !(PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) { - PHPDBG_G(lcmd) = (phpdbg_command_t*) command; - phpdbg_clear_param( - &PHPDBG_G(lparam) TSRMLS_CC); - PHPDBG_G(lparam) = param; + if (rc != FAILURE && !(PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) { + phpdbg_clear_param(&initial_last_param TSRMLS_CC); + } else if (PHPDBG_G(lcmd) == command && !memcmp(&PHPDBG_G(lparam),& initial_last_param, sizeof(phpdbg_param_t))) { + PHPDBG_G(lparam) = initial_last_param; + PHPDBG_G(lcmd) = initial_last_cmd; + phpdbg_clear_param(¶m TSRMLS_CC); } break; } From 992a8d0411535811006c1ba2be4723127995a88f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 18 Jan 2014 18:48:53 -0500 Subject: [PATCH 020/137] Clean root symbol table when starting new execution --- phpdbg_prompt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index cb46407957c..529ab04194d 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -566,6 +566,12 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_rebuild_symbol_table(TSRMLS_C); } + /* clean up from last execution */ + zend_execute_data *ex = EG(current_execute_data); + if (ex && ex->symbol_table) { + zend_hash_clean(ex->symbol_table); + } + /* clean seek state */ PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK; zend_hash_clean( From f27be2fded6b75cac1b13bd237c3ae0d8238a40d Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 18 Jan 2014 19:24:22 -0500 Subject: [PATCH 021/137] Fixed order of instructions... --- phpdbg_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 69585a720f2..dee3b6da19b 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -657,9 +657,9 @@ PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *in } } - PHPDBG_G(lparam) = param; initial_last_param = PHPDBG_G(lparam); initial_last_cmd = (phpdbg_command_t *)PHPDBG_G(lcmd); + PHPDBG_G(lparam) = param; PHPDBG_G(lcmd) = (phpdbg_command_t *)command; rc = command->handler(¶m, input TSRMLS_CC); From ab16299355c4c739668a2d96a1075fd67c70bd62 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 18 Jan 2014 20:36:56 -0500 Subject: [PATCH 022/137] Removed some segfault; does still not delete all the watches if var is removed, might segfault --- phpdbg_watch.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index a0b9d19dcc8..18c3f447a65 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -39,11 +39,11 @@ typedef struct { #define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) -static inline void *phpdbg_get_page_boundary(void *addr) { +static zend_always_inline void *phpdbg_get_page_boundary(void *addr) { return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); } -static inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { +static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } @@ -381,22 +381,19 @@ int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { } int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { - void *addr; void *page; phpdbg_watch_memdump *dump; phpdbg_watchpoint_t *watch; size_t size; - addr = info->si_addr; - - watch = phpdbg_check_for_watchpoint(addr TSRMLS_CC); + watch = phpdbg_check_for_watchpoint(info->si_addr TSRMLS_CC); if (watch == NULL) { return FAILURE; } - page = phpdbg_get_page_boundary(addr); - size = phpdbg_get_total_page_size(addr, watch->size); + page = phpdbg_get_page_boundary(watch->addr.ptr); + size = phpdbg_get_total_page_size(watch->addr.ptr, watch->size); /* re-enable writing */ mprotect(page, size, PROT_NONE | PROT_READ | PROT_WRITE); @@ -495,8 +492,12 @@ static int phpdbg_print_changed_zval(void *llist_data) { zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); - if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) { + if (Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) { + break; + } + remove_ht_watch: + if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) { htwatch = htresult->ptr; zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len); } From 2e4aed3673607fda63edaac2b9b69669c5c1ceec Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 19 Jan 2014 12:25:24 +0100 Subject: [PATCH 023/137] Merge branch PHP-5.6 of php-src --- phpdbg_cmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index dee3b6da19b..8429ce280e1 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -459,6 +459,9 @@ PHPDBG_API phpdbg_input_t *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { phpdbg_input_t *buffer = NULL; char *cmd = NULL; +#ifndef HAVE_LIBREADLINE + char buf[PHPDBG_MAX_CMD]; +#endif if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && @@ -475,7 +478,6 @@ disconnect: } #ifndef HAVE_LIBREADLINE - char buf[PHPDBG_MAX_CMD]; if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { if (!phpdbg_write(phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; From 1c0fccfc9abaaea02ae717547bc3b69fcb2de86c Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 27 Jan 2014 07:39:34 +0000 Subject: [PATCH 024/137] fix readline build error bugsnet #66576 --- config.m4 | 7 ++++++- phpdbg.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/config.m4 b/config.m4 index 274e6409d04..3ad53ba8979 100644 --- a/config.m4 +++ b/config.m4 @@ -20,9 +20,14 @@ if test "$PHP_PHPDBG" != "no"; then PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c" + if test "$PHP_READLINE" != "no"; then + PHPDBG_EXTRA_LIBS="-lreadline" + fi + PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) - + PHP_SUBST(PHPDBG_EXTRA_LIBS) + PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/phpdbg/Makefile.frag]) PHP_SELECT_SAPI(phpdbg, program, $PHP_PHPDBG_FILES, $PHP_PHPDBG_CFLAGS, [$(SAPI_PHPDBG_PATH)]) diff --git a/phpdbg.h b/phpdbg.h index 6b7afb23704..68c505ca636 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -149,7 +149,7 @@ #define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ #define PHPDBG_URL "http://phpdbg.com" #define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" -#define PHPDBG_VERSION "0.3.1" +#define PHPDBG_VERSION "0.3.2" #define PHPDBG_INIT_FILENAME ".phpdbginit" /* }}} */ From c768abd420b92dca952ca5b39d6ea0a4395d802b Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 28 Jan 2014 17:23:29 +0000 Subject: [PATCH 025/137] fix bugsnet #66594, thanks ondrej@php.net --- phpdbg_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 8429ce280e1..1d78c533216 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -479,7 +479,7 @@ disconnect: #ifndef HAVE_LIBREADLINE if (!(PHPDBG_G(flags) & PHPDBG_IS_REMOTE)) { - if (!phpdbg_write(phpdbg_get_prompt(TSRMLS_C))) { + if (!phpdbg_write("%s", phpdbg_get_prompt(TSRMLS_C))) { goto disconnect; } } From 261a5305c6b3528ec45d6e185c50dbac61916dd6 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 29 Jan 2014 07:28:54 +0000 Subject: [PATCH 026/137] fix bugsnet #66591 and github #60 --- phpdbg.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phpdbg.c b/phpdbg.c index e7f841c0bca..179424bf943 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -831,7 +831,13 @@ int main(int argc, char **argv) /* {{{ */ zend_bool remote = 0; int run = 0; int step = 0; + +#ifdef _WIN32 char *bp_tmp_file; +#else + char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX"; +#endif + #ifndef _WIN32 char *address; int listen[2]; @@ -871,8 +877,12 @@ int main(int argc, char **argv) /* {{{ */ phpdbg_main: if (!cleaning) { +#ifdef _WIN32 bp_tmp_file = malloc(L_tmpnam); tmpnam(bp_tmp_file); +#else + mkstemp(bp_tmp_file); +#endif if (bp_tmp_file == NULL) { phpdbg_error("Unable to create temporary file"); } @@ -1342,7 +1352,11 @@ phpdbg_out: free(sapi_name); } +#ifdef _WIN32 free(bp_tmp_file); +#else + unlink(bp_tmp_file); +#endif return 0; } /* }}} */ From e55bd70643d9e9c8b3f0a6d141dc2ca3d0ef024c Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 2 Feb 2014 13:29:34 +0000 Subject: [PATCH 027/137] scrap using zend directly, too many leaks/bugs --- phpdbg.c | 43 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 34 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 179424bf943..2a10ada9329 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -879,6 +879,7 @@ phpdbg_main: if (!cleaning) { #ifdef _WIN32 bp_tmp_file = malloc(L_tmpnam); + tmpnam(bp_tmp_file); #else mkstemp(bp_tmp_file); @@ -1127,8 +1128,7 @@ phpdbg_main: phpdbg->ini_entries = ini_entries; if (phpdbg->startup(phpdbg) == SUCCESS) { - - zend_activate(TSRMLS_C); + php_request_startup(TSRMLS_C); /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ @@ -1196,20 +1196,11 @@ phpdbg_main: /* set default prompt */ phpdbg_set_prompt(PROMPT TSRMLS_CC); - zend_try { - zend_activate_modules(TSRMLS_C); - } zend_end_try(); - if (show_banner) { /* print blurb */ phpdbg_welcome((cleaning > 0) TSRMLS_CC); } - zend_try { - /* activate globals, they can be overwritten */ - zend_activate_auto_globals(TSRMLS_C); - } zend_end_try(); - /* initialize from file */ PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { @@ -1279,12 +1270,6 @@ phpdbg_interact: } zend_end_try(); } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); - /* this must be forced */ - CG(unclean_shutdown) = 0; - - /* this is just helpful */ - PG(report_memleaks) = 0; - phpdbg_out: #ifndef _WIN32 if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { @@ -1307,24 +1292,14 @@ phpdbg_out: if (ini_override) { free(ini_override); } + + /* this must be forced */ + CG(unclean_shutdown) = 0; + + /* this is just helpful */ + PG(report_memleaks) = 0; - if (PG(modules_activated)) { - zend_try { - zend_deactivate_modules(TSRMLS_C); - } zend_end_try(); - } - - zend_deactivate(TSRMLS_C); - - zend_try { - zend_post_deactivate_modules(TSRMLS_C); - } zend_end_try(); - -#ifdef ZEND_SIGNALS - zend_try { - zend_signal_deactivate(TSRMLS_C); - } zend_end_try(); -#endif + php_request_shutdown((void*)0); zend_try { php_module_shutdown(TSRMLS_C); From 0c94f8a8934211694bab200507786248185e2dfd Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 2 Feb 2014 14:41:51 +0000 Subject: [PATCH 028/137] ... --- phpdbg.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 2a10ada9329..9341ad35a50 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -833,7 +833,7 @@ int main(int argc, char **argv) /* {{{ */ int step = 0; #ifdef _WIN32 - char *bp_tmp_file; + char *bp_tmp_file = NULL; #else char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX"; #endif @@ -877,14 +877,23 @@ int main(int argc, char **argv) /* {{{ */ phpdbg_main: if (!cleaning) { + #ifdef _WIN32 bp_tmp_file = malloc(L_tmpnam); - tmpnam(bp_tmp_file); + if (bp_tmp_file) { + if (!tmpnam(bp_tmp_file)) { + free(bp_tmp_file); + bp_tmp_file = NULL; + } + } #else - mkstemp(bp_tmp_file); + if (!mkstemp(bp_tmp_file)) { + memset(bp_tmp_file, 0, sizeof(bp_tmp_file)); + } #endif - if (bp_tmp_file == NULL) { + + if (!bp_tmp_file) { phpdbg_error("Unable to create temporary file"); } } From f88ff6c661077df281ff16880f111a0d974e239c Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 2 Feb 2014 14:51:30 +0000 Subject: [PATCH 029/137] woops --- phpdbg.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 9341ad35a50..6cb1645e65a 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -892,9 +892,11 @@ phpdbg_main: memset(bp_tmp_file, 0, sizeof(bp_tmp_file)); } #endif - + if (!bp_tmp_file) { - phpdbg_error("Unable to create temporary file"); + phpdbg_error( + "Unable to create temporary file"); + return 1; } } ini_entries = NULL; From 891477dc1c3ae795708c022e3e023c5a7b7e0128 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 2 Feb 2014 15:16:01 +0000 Subject: [PATCH 030/137] windows --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 529ab04194d..f586bb5a84f 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -552,6 +552,7 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_op_array *orig_op_array = EG(active_op_array); zval **orig_retval_ptr = EG(return_value_ptr_ptr); zend_bool restore = 1; + zend_execute_data *ex = EG(current_execute_data); if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { @@ -567,7 +568,6 @@ PHPDBG_COMMAND(run) /* {{{ */ } /* clean up from last execution */ - zend_execute_data *ex = EG(current_execute_data); if (ex && ex->symbol_table) { zend_hash_clean(ex->symbol_table); } From 88bd558a73e9b29c05b5cc3e9bb78aee46ac5ee0 Mon Sep 17 00:00:00 2001 From: Terry Ellison Date: Sun, 2 Feb 2014 16:35:28 +0000 Subject: [PATCH 031/137] Work in progress chekpoint of changes to help module. To allow peer review and feedback --- phpdbg_break.c | 16 + phpdbg_break.h | 16 +- phpdbg_help.c | 1398 +++++++++++++++++++++++++++++------------------ phpdbg_help.h | 60 +- phpdbg_info.c | 12 + phpdbg_info.h | 12 +- phpdbg_list.c | 8 + phpdbg_list.h | 8 +- phpdbg_print.c | 10 + phpdbg_print.h | 13 +- phpdbg_prompt.c | 71 --- phpdbg_prompt.h | 1 - phpdbg_set.c | 11 + phpdbg_set.h | 11 +- phpdbg_utils.c | 21 + phpdbg_utils.h | 3 + 16 files changed, 948 insertions(+), 723 deletions(-) diff --git a/phpdbg_break.c b/phpdbg_break.c index f56f76facd9..67267550c54 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -27,6 +27,22 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +/** + * Commands + */ +const phpdbg_command_t phpdbg_break_commands[] = { + PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, 1), + PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, 1), + PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, 1), + PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, 1), + PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, 1), + PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1), + PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, 1), + PHPDBG_END_COMMAND +}; + PHPDBG_BREAK(file) /* {{{ */ { switch (param->type) { diff --git a/phpdbg_break.h b/phpdbg_break.h index f90e351d6de..38f1298c932 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -39,20 +39,6 @@ PHPDBG_BREAK(on); PHPDBG_BREAK(lineno); PHPDBG_BREAK(del); -/** - * Commands - */ -static const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, 1), - PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, 1), - PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, 1), - PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, 1), - PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, 1), - PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1), - PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, 1), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_break_commands[]; #endif /* PHPDBG_BREAK_H */ diff --git a/phpdbg_help.c b/phpdbg_help.c index a02cb41c143..ec0af2ac79d 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -15,589 +15,899 @@ | Authors: Felipe Pena | | Authors: Joe Watkins | | Authors: Bob Weinand | + | Authors: Terry Ellison | +----------------------------------------------------------------------+ */ #include "phpdbg.h" #include "phpdbg_help.h" +#include "phpdbg_prompt.h" #include "phpdbg_print.h" #include "phpdbg_utils.h" #include "phpdbg_break.h" #include "phpdbg_list.h" #include "phpdbg_info.h" #include "phpdbg_set.h" +#include "zend.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -PHPDBG_HELP(exec) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("\tWill attempt execution, if compilation has not yet taken place, it occurs now"); - phpdbg_writeln("The execution context must be set before execution can take place"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ +/* {{{ Commands Table */ +#define PHPDBG_COMMAND_HELP_D(name, tip, alias, action) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, action, NULL, 0} -PHPDBG_HELP(step) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("You can enable and disable stepping at any phpdbg prompt during execution"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sstepping 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%ss 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill enable stepping"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("While stepping is enabled you are presented with a prompt after the execution of each opcode"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ +const phpdbg_command_t phpdbg_help_commands[] = { + PHPDBG_COMMAND_HELP_D(aliases, "show alias list", 'a', phpdbg_do_help_aliases), + PHPDBG_COMMAND_HELP_D(options, "command line options", 0, NULL), + PHPDBG_COMMAND_HELP_D(overview, "help overview", 0, NULL), + PHPDBG_COMMAND_HELP_D(phpdbginit, "phpdbginit file format", 0, NULL), + PHPDBG_COMMAND_HELP_D(syntax, "syntax overview", 0, NULL), + PHPDBG_END_COMMAND +}; /* }}} */ -PHPDBG_HELP(next) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_write("Step back into the vm and execute the next opcode"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%snext", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sn", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: is only useful while executing"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ +/* {{{ pretty_format. Takes a text string, expands any formatting escapes and wrap the text */ +static char *pretty_format(char *text TSRMLS_DC) { + char *new, *p, *q; -PHPDBG_HELP(until) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Step back into the vm, skipping breakpoints until the next source line"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%suntil", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%su", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: is only useful while executing"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + const char *prompt_escape = phpdbg_get_prompt(TSRMLS_C); + unsigned int prompt_escape_len = strlen(prompt_escape); + unsigned int prompt_len = strlen(PHPDBG_G(prompt)[0]); -PHPDBG_HELP(finish) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Step back into the vm, skipping breakpoints until past the end of the current stack"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sfinish", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sF", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill cause control to be passed back to the vm, continuing execution"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: this allows all breakpoints that would otherwise break execution in the current scope to be skipped"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + const char *bold_on_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[1m" : ""; + const char *bold_off_escape = PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "\033[0m" : ""; + unsigned int bold_escape_len = strlen(bold_on_escape); -PHPDBG_HELP(leave) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Step back into the vm, skipping breakpoints until the current stack is returning"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sleave", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sL", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill cause a break when instructed to leave the current context"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: this allows inspection of the return value before it is returned"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + unsigned int term_width = phpdbg_get_terminal_width(TSRMLS_C); + unsigned int size = 0; -PHPDBG_HELP(compile) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Pre-compilation of the execution context provides the opportunity to inspect opcodes before execution"); - phpdbg_writeln("The execution context must be set for compilation to succeed"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%scompile", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sc", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill compile the current execution context, populating class/function/constant/etc tables"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: It is a good idea to clean the environment between each compilation"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + int in_bold = 0; -PHPDBG_HELP(print) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("By default, print will show information about the current execution context"); - phpdbg_writeln("Other printing commands give access to instruction information"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sprint class \\my\\class", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp c \\my\\class", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for the methods in \\my\\class"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint method \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp m \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for \\my\\class::method"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint func .getSomething", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp f .getSomething", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for ::getSomething in the active scope"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint func my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp f my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for the global function my_function"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint opline", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp o", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instruction for the current opline"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint exec", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp e", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for the execution context"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sprint stack", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sp s", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the instructions for the current stack"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Specific printers loaded are show below:"); - phpdbg_notice("Commands"); - { - const phpdbg_command_t *print_command = phpdbg_print_commands; + char *last_new_blank = NULL; /* position in new buffer of last blank char */ + unsigned int last_blank_count = 0; /* printable char offset of last blank char */ + unsigned int line_count = 0; /* number printable chars on current line */ - phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); - while (print_command && print_command->name) { - if (print_command->alias) { - phpdbg_writeln("\t[%c]\t%s\t\t%s", print_command->alias, print_command->name, print_command->tip); - } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", print_command->name, print_command->tip); - } - ++print_command; + /* First pass calculates a safe size for the pretty print version */ + for (p = text; *p; p++) { + if ( UNEXPECTED(p[0] == '*') && p[1] == '*' ) { + size += bold_escape_len - 2; + p++; + } else if ( UNEXPECTED(p[0] == '$') && p[1] == 'P' ) { + size += prompt_escape_len - 2; + p++; + } else if ( UNEXPECTED(p[0] == '\\') ) { + p++; } } - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ + size += (p-text)+1; -PHPDBG_HELP(run) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Execute the current context inside the phpdbg vm"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%srun", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sr", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill cause execution of the context, if it is set."); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: The execution context must be set, but not necessarily compiled before execution occurs"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(eval) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Access to eval() allows you to change the environment during execution, careful though!!"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%seval $variable", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sE $variable", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print_r($variable) on the console, if it is defined"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%seval $variable = \"Hello phpdbg :)\"", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sE $variable = \"Hello phpdbg :)\"", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill set $variable in the current scope"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: eval() will always show the result; do not prefix the code with \"return\""); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(break) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Setting a breakpoint stops execution at a specific stage"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sbreak [file] test.php:1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [F] test.php:1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break execution on line 1 of test.php"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [func] my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [f] my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break execution on entry to my_function"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [method] \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [m] \\my\\class::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break execution on entry to \\my\\class::method"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [address] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [a] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at the opline with the address provided"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [address] my_function#1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [a] my_function#1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at the opline number 1 of the function my_function"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [address] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [a] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at the opline number 2 of the method \\my\\class::method"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak address test.php:3", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb a test.php:3", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at the opline number 3 of test.php"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak [lineno] 200", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb [l] 200", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at line 200 of the currently executing file"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak on ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb on ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break when the condition evaluates to true"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak at phpdbg::isGreat if ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at every opcode in phpdbg::isGreat when the condition evaluates to true"); - phpdbg_writeln("\t%sbreak at test.php:20 if ($expression == true)", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break at every opcode on line 20 of test.php when the condition evaluates to true"); - phpdbg_write("\t"); - phpdbg_notice("The location can be anything accepted by file, func, method, or address break commands"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak op ZEND_ADD", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb O ZEND_ADD", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill break on every occurence of the opcode provided"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%sbreak del 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sb d 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill remove the breakpoint with the given identifier"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: An address is only valid for the current compilation"); - phpdbg_writeln(EMPTY); - phpdbg_notice("The parameters enclosed by [] are usually optional, but help avoid ambigious commands"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Specific breakers loaded are show below:"); - phpdbg_notice("Commands"); - { - const phpdbg_command_t *break_command = phpdbg_break_commands; - - phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); - while (break_command && break_command->name) { - if (break_command->alias) { - phpdbg_writeln("\t[%c]\t%s\t\t%s", break_command->alias, break_command->name, break_command->tip); - } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", break_command->name, break_command->tip); + new = emalloc(size); + /* + * Second pass substitutes the bold and prompt escape sequences and line wrap + * + * ** toggles bold on and off if PHPDBG_IS_COLOURED flag is set + * $P substitutes the prompt sequence + * Lines are wrapped by replacing the last blank with a CR before + * characters. (This defaults to 100 if the width can't be detected). In the + * pathelogical case where no blanks are found, then the wrap occurs at the + * first blank. + */ + for (p = text, q = new; *p; p++) { + if ( UNEXPECTED(*p == ' ') ) { + last_new_blank = q; + last_blank_count = line_count++; + *q++ = ' '; + } else if ( UNEXPECTED(*p == '\n') ) { + last_new_blank = NULL; + *q++ = *p; + last_blank_count = 0; + line_count = 0; + } else if ( UNEXPECTED(p[0] == '*') && p[1] == '*' ) { + if (bold_escape_len) { + in_bold = !in_bold; + memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); + q += bold_escape_len; + /* bold on/off has zero print width so line count is unchanged */ } - ++break_command; - } - } - phpdbg_writeln("Note: Conditional breaks are costly, use them sparingly!"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(clean) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("While debugging you may experience errors because of attempts to redeclare classes, constants or functions"); - phpdbg_writeln("Cleaning the environment cleans these tables, so that files can be recompiled without exiting phpdbg"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(clear) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Clearing breakpoints means you can once again run code without interruption"); - phpdbg_writeln("Note: all breakpoints are lost; be sure debugging is complete before clearing"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(info) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("info commands provide quick access to various types of information about the PHP environment"); - phpdbg_writeln("Specific info commands are show below:"); - phpdbg_notice("Commands"); - { - const phpdbg_command_t *info_command = phpdbg_info_commands; - - phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); - while (info_command && info_command->name) { - if (info_command->alias) { - phpdbg_writeln("\t[%c]\t%s\t\t%s", info_command->alias, info_command->name, info_command->tip); - } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", info_command->name, info_command->tip); - } - ++info_command; - } - } - - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(quiet) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Setting quietness on will stop the OPLINE output during execution"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%squiet 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sQ 1", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill silence OPLINE output, while"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%squiet 0", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sQ 0", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill enable OPLINE output again"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: Quietness is disabled automatically while stepping"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(back) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("The backtrace is built with the default debug backtrace functionality"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sback 5", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%st 5", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill limit the number of frames to 5, the default is no limit"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: it is not necessary for an exception to be thrown to show a backtrace"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(frame) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("When viewing a backtrace, it is sometimes useful to jump to a frame in that trace"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sframe 2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sf 2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill go to frame 2, temporarily affecting scope and allowing access to the variables in that frame"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: the current frame is restored when execution continues"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(list) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("The list command displays source code for the given argument"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%slist [lines] 2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sl [l] 2", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print next 2 lines from the current file"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%slist [func] my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sl [f] my_function", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the source of the global function \"my_function\""); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%slist [func] .mine", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sl [f] .mine", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the source of the method \"mine\" from the active scope"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%slist [method] my::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sl [m] my::method", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the source of \"my::method\""); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%slist c myClass", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sl c myClass", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill print the source of \"myClass\""); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: before listing functions you must have a populated function table, try compile!!"); - phpdbg_writeln(EMPTY); - phpdbg_notice("The parameters enclosed by [] are usually optional, but help avoid ambigious commands"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Specific listers loaded are show below:"); - phpdbg_notice("Commands"); - { - const phpdbg_command_t *list_command = phpdbg_list_commands; - - phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); - while (list_command && list_command->name) { - if (list_command->alias) { - phpdbg_writeln("\t[%c]\t%s\t\t%s", list_command->alias, list_command->name, list_command->tip); - } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", list_command->name, list_command->tip); - } - ++list_command; - } - } - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(oplog) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Even when quietness is enabled you may wish to save opline logs to a file"); - phpdbg_writeln("Setting a new oplog closes the previously open log"); - phpdbg_writeln("The log includes a high resolution timestamp on each entry"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%soplog /path/to/my.oplog", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sO /path/to/my.oplog", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill open the file /path/to/my.oplog for writing, creating it if it does not exist"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("\t%soplog 0", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sO 0", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill close the currently open log file, disabling oplog"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: upon failure to open a new oplog, the last oplog is held open"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ - -PHPDBG_HELP(set) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Configure how phpdbg looks and behaves with the set command"); - phpdbg_writeln("Specific set commands are show below:"); - phpdbg_notice("Commands"); - { - const phpdbg_command_t *set_command = phpdbg_set_commands; - - phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); - while (set_command && set_command->name) { - if (set_command->alias) { - phpdbg_writeln("\t[%c]\t%s\t\t%s", set_command->alias, set_command->name, set_command->tip); - } else { - phpdbg_writeln("\t[ ]\t%s\t\t%s", set_command->name, set_command->tip); - } - ++set_command; - } - } -#ifndef _WIN32 - phpdbg_notice("Colors"); - { - const phpdbg_color_t *color = phpdbg_get_colors(TSRMLS_C); - - if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - phpdbg_writeln("\t%-20s\t\tExample", "Name"); + p++; + } else if ( UNEXPECTED(p[0] == '$') && p[1] == 'P' ) { + memcpy (q, prompt_escape, prompt_escape_len); + q += prompt_escape_len; + line_count += prompt_len; + p++; + } else if ( UNEXPECTED(p[0] == '\\') ) { + p++; + *q++ = *p; + line_count++; } else { - phpdbg_writeln("\tName"); + *q++ = *p; + line_count++; } - - while (color && color->name) { - if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) { - phpdbg_writeln( - "\t%-20s\t\t\033[%smphpdbg rocks :)\033[0m", color->name, color->code); - } else { - phpdbg_writeln("\t%s", color->name); + + if (UNEXPECTED(line_count>=term_width) && last_new_blank) { + *last_new_blank = '\n'; + last_new_blank = NULL; + line_count -= last_blank_count; + last_blank_count = 0; + } + } + *q++ = '\0'; + + if ((q-new)>size) { + phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); + } + return new; +} /* }}} */ + +/* {{{ get_help. Retries and formats text from the phpdbg help text table */ +static char *get_help(const char * const key TSRMLS_DC) { + phpdbg_help_text_t *p = phpdbg_help_text; + + /* note that phpdbg_help_text is collated in key order */ + for( ;p->key[0]key[0]==key[0]) { + if (!strcmp(p->key+1, key+1)) { + return p->text; + } + p++; + } + return estrdup(""); /* return empty string to denote no match found */ +} /* }}} */ + +/* {{{ get_command. Return one or more matching commands from a command table. + * Unlike the command parser, the help search is sloppy that is partial matches can occur + * * Any single character key is taken as an alias and only an exact match is allowed + * * Other keys are matched again the table on the first len characters. + * * This means that non-unique keys can generate multiple matches + * * The command summary is an emalloced string containing one line for each match + * * The function only returns a command entry if a unique match occurs. + * + * The rationale here is to assist users in finding help on commands. So "h fr" will + * generate a summary line for "help frame" and return the frame record. But "h cl" will + * generate two summary records for the "clear" and "clean" and a NULL command record. + */ +#define ALIAS_FMT "Command: **%s** Alias: **%c** **%s**\n" +static const phpdbg_command_t *get_command( + const char *key, size_t len, /* pointer and length of key */ + char **command_summary, /* address of command summary text */ + const phpdbg_command_t * const commands /* command table to be scanned */ + TSRMLS_DC) { + const phpdbg_command_t *c, *c_found; + unsigned int num_matches = 0; + char *summary; + + if (len == 1) { + for (c=commands; c->name; c++) { + if (c->alias == key[0]) { + num_matches++; + if (command_summary) { + spprintf(&summary, 0, ALIAS_FMT, c->name, c->alias, c->tip); + } + c_found = c; + break; + } + } + } else { + for (c=commands; c->name; c++) { + if (!strncmp(c->name, key, len)) { + ++num_matches; + c_found = c; + if (command_summary) { + if (num_matches == 1) { + spprintf(&summary, 0, ALIAS_FMT, c->name, c->alias, c->tip); + } else { /* num_matches > 1 */ + /* very rare so "keep it simple" string concat of summaries */ + char *tmp = summary; + spprintf(&summary, 0, "%s" ALIAS_FMT, tmp, c->name, c->alias, c->tip); + efree(tmp); + } + } } - ++color; } } - phpdbg_writeln("The for set color can be \"prompt\", \"notice\", or \"error\""); -#endif - phpdbg_help_footer(); - return SUCCESS; + + if (command_summary) { + *command_summary = (num_matches > 0) ? summary : NULL; + } + return (num_matches == 1) ? c_found : NULL; /* NULL return denotes no single match found */ + } /* }}} */ -PHPDBG_HELP(register) /* {{{ */ +PHPDBG_COMMAND(help) /* {{{ */ { - phpdbg_help_header(); - phpdbg_writeln("Register any global function for use as a command in phpdbg console"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sregister scandir", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%sR scandir", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill register the scandir function for use in phpdbg"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: arguments passed as strings, return (if present) print_r'd on console"); - if (zend_hash_num_elements(&PHPDBG_G(registered))) { - HashPosition position; - char *name = NULL; - zend_uint name_len = 0; + char *banner, *help_text, *pretty_banner, *pretty_help_text; + const phpdbg_command_t *cmd; - phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered))); - for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(registered), &position); - zend_hash_get_current_key_ex(&PHPDBG_G(registered), &name, &name_len, NULL, 1, &position) == HASH_KEY_IS_STRING; - zend_hash_move_forward_ex(&PHPDBG_G(registered), &position)) { - phpdbg_writeln("|-------> %s", name); - efree(name); - } + if (param->type == EMPTY_PARAM) { + char * help_text = pretty_format(get_help("_overview" TSRMLS_CC) TSRMLS_CC); + phpdbg_write("\n%s\n", help_text); + efree(help_text); + return SUCCESS; } - phpdbg_help_footer(); + if (param->type == STR_PARAM) { + cmd = get_command( param->str, param->len, &banner, phpdbg_prompt_commands TSRMLS_CC); + + if (banner) { + pretty_banner = pretty_format(banner TSRMLS_CC); + help_text = get_help((cmd ? cmd->name : "_ZZ_duplicate") TSRMLS_CC); + pretty_help_text = pretty_format(help_text TSRMLS_CC); + phpdbg_write("%s\n%s\n", pretty_banner, pretty_help_text); + efree(banner); + efree(pretty_banner); + efree(pretty_help_text); + return SUCCESS; + + } else if (param->type == STR_PARAM) { + cmd = get_command( param->str, param->len, NULL, phpdbg_help_commands TSRMLS_CC); + if (cmd) { + char *name; + spprintf(&name, cmd->name_len+2, "_%s", cmd->name); + help_text = get_help(name TSRMLS_CC); + pretty_help_text = pretty_format(help_text TSRMLS_CC); + phpdbg_write("%s\n", pretty_help_text); + efree(pretty_help_text); + efree(name); + return SUCCESS; + } + } + } + + phpdbg_error("No help can be found for the subject \"%s\"", param->str); + return FAILURE; + + +} /* }}} */ + +PHPDBG_HELP(aliases) /* {{{ */ +{ + const phpdbg_command_t *c, *c_sub; + char *help_text; + int len; + + /* Print out aliases for all commands except help as this one comes last */ + phpdbg_writeln("Below are the aliased, short versions of all supported commands"); + for(c = phpdbg_prompt_commands; c->name; c++) { + if (c->alias && c->alias != 'h') { + phpdbg_writeln(" %c %-20s %s", c->alias, c->name, c->tip); + if (c->subs) { + len = 20 - 1 - c->name_len; + for(c_sub = c->subs; c_sub->alias; c_sub++) { + if (c_sub->alias) { + phpdbg_writeln(" %c %c %s %-*s %s", + c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); + } + } + phpdbg_writeln(EMPTY); + } + } + } + + /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ + c = get_command( "h", 1, NULL, phpdbg_prompt_commands TSRMLS_CC); + phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip); + len = 20 - 1 - c->name_len; + for(c_sub = c->subs; c_sub->alias; c_sub++) { + if (c_sub->alias) { + phpdbg_writeln(" %c %c %s %-*s %s", + c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); + } + } + help_text = pretty_format(get_help("_ZZ_aliases" TSRMLS_CC) TSRMLS_CC); + phpdbg_write("\n%s\n", help_text); + efree(help_text); + return SUCCESS; } /* }}} */ -PHPDBG_HELP(source) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Sourcing a phpdbginit during your debugging session might save some time"); - phpdbg_writeln("The source command can also be used to export breakpoints to a phpdbginit file"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%ssource /my/init", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%s. /my/init", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill execute the phpdbginit file at /my/init"); - phpdbg_writeln("\t%ssource export /my/init", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%s. export /my/init", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill export breakpoints to /my/init in phpdbginit file format"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ -PHPDBG_HELP(shell) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Direct access to shell commands saves having to switch windows/consoles"); - phpdbg_writeln(EMPTY); - phpdbg_notice("Examples"); - phpdbg_writeln("\t%sshell ls /usr/src/php-src", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\t%s- ls /usr/src/php-src", phpdbg_get_prompt(TSRMLS_C)); - phpdbg_writeln("\tWill execute ls /usr/src/php-src, displaying the output in the console"); - phpdbg_writeln(EMPTY); - phpdbg_writeln("Note: read only commands please!"); - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ +/* {{{ Help Text Table + * Contains help text entries keyed by a lowercase ascii key. + * Text is in ascii and enriched by a simple markup: + * ** toggles bold font emphasis. + * $P insert an bold phpdbg> prompt. + * \ escapes the following character. Note that this is itself escaped inside string + * constants so \\\\ is required to output a single \ e.g. as in namespace names. + * + * Text will be wrapped according to the STDOUT terminal width, so paragraphs are + * flowed using the C stringizing and the CR definition. Also note that entries + * are collated in alphabetic order on key. + */ +#define CR "\n" +phpdbg_help_text_t phpdbg_help_text[] = { +{"_options", +"Below are the command line options supported by phpdbg" CR CR + /* note the extra 4 space index in because of the extra **** */ +"**Command Line Options and Flags**" CR +" **Option** **Example Argument** **Description**" CR +" **-c** **-c**/my/php.ini Set php.ini file to load" CR +" **-d** **-d**memory_limit=4G Set a php.ini directive" CR +" **-n** Disable default php.ini" CR +" **-q** Supress welcome banner" CR +" **-e** **-e**mytest.php Set execution context" CR +" **-v** Enable oplog output" CR +" **-s** Enable stepping" CR +" **-b** Disable colour" CR +" **-i** **-i**my.init Set .phpdbginit file" CR +" **-I** Ignore default .phpdbginit" CR +" **-O** **-O**my.oplog Sets oplog output file" CR +" **-r** Run execution context" CR +" **-rr** Run execution context and quit after execution" CR +" **-E** Enable step through eval, careful!" CR +" **-S** **-S**cli Override SAPI name, careful!" CR +" **-l** **-l**4000 Setup remote console ports" CR +" **-a** **-a**192.168.0.3 Setup remote console bind address" CR +" **-V** Print version number" CR CR -PHPDBG_HELP(options) /* {{{ */ -{ - phpdbg_help_header(); - phpdbg_writeln("Below are the command line options supported by phpdbg"); - phpdbg_notice("Command Line Options and Flags"); - phpdbg_writeln(" -c\t-c/my/php.ini\t\tSet php.ini file to load"); - phpdbg_writeln(" -d\t-dmemory_limit=4G\tSet a php.ini directive"); - phpdbg_writeln(" -n\tN/A\t\t\tDisable default php.ini"); - phpdbg_writeln(" -q\tN/A\t\t\tSupress welcome banner"); - phpdbg_writeln(" -e\t-emytest.php\t\tSet execution context"); - phpdbg_writeln(" -v\tN/A\t\t\tEnable oplog output"); - phpdbg_writeln(" -s\tN/A\t\t\tEnable stepping"); - phpdbg_writeln(" -b\tN/A\t\t\tDisable colour"); - phpdbg_writeln(" -i\t-imy.init\t\tSet .phpdbginit file"); - phpdbg_writeln(" -I\tN/A\t\t\tIgnore default .phpdbginit"); - phpdbg_writeln(" -O\t-Omy.oplog\t\tSets oplog output file"); - phpdbg_writeln(" -r\tN/A\t\t\tRun execution context"); - phpdbg_writeln(" -E\tN/A\t\t\tEnable step through eval, careful!"); - phpdbg_writeln(" -S\t-Scli\t\t\tOverride SAPI name, careful!"); -#ifndef _WIN32 - phpdbg_writeln(" -l\t-l4000\t\t\tSetup remote console ports"); - phpdbg_writeln(" -a\t-a192.168.0.3\t\tSetup remote console bind address"); -#endif - phpdbg_writeln(" -V\tN/A\t\t\tVersion number"); - phpdbg_notice("Passing -rr will quit automatically after execution"); -#ifndef _WIN32 - phpdbg_writeln("Remote Console Mode"); - phpdbg_notice("For security, phpdbg will bind only to the loopback interface by default"); - phpdbg_writeln("-a without an argument implies all; phpdbg will bind to all available interfaces."); - phpdbg_writeln("specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2."); - phpdbg_notice("Steps should be taken to secure this service if bound to a public interface/port"); -#endif - phpdbg_help_footer(); - return SUCCESS; -} /* }}} */ +"**Remote Console Mode**" CR CR + +"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback " +"interface by default, and this can only be overridden by explicitly setting the remote console " +"bind address using the **-a** option. If **-a** is specied without an argument, then phpdbg " +"will bind to all available interfaces. You should be aware of the security implications of " +"doing this, so measures should be taken to secure this service if bound to a publicly accessible " +"interface/port." CR CR + +"Specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2." +}, + +{"_overview", +"**phpdbg** is a lightweight, powerful and easy to use debugging platform for PHP5.4+" CR +"It supports the following commands:" CR CR + +"**Information**" CR +" **list** list PHP source" CR +" **info** displays information on the debug session" CR +" **help** provide help on a topic" CR +" **print** print argument " CR +" **frame** select a stack frame and print a stack frame summary" CR CR + +"**Compilation**" CR +" **compile** compile a PHP source" CR CR + +"**Starting and Stopping Execution**" CR +" **exec** set execution context" CR +" **clean** clean the execution environment" CR +" **run** attempt execution" CR +" **eval** evaluate some code" CR +" **stepping** Enable or disable per opcode stepping mode" CR +" **next** continue execution" CR +" **until** continue execution up to the given location" CR +" **finish** continue up to end of the current execution frame" CR +" **leave** continue up to end of the current execution frame and halt after the calling instruction" CR +" **break** set a breakpoint at the specified target" CR +" **clear** clear one or all breakpoints" CR CR + +"**Miscellaneous**" CR +" **quiet** silence some output" CR +" **set** set the phpdbg configuration" CR +" **source** execute a phpdbginit script" CR +" **register** register a phpdbginit function as a command alias" CR +" **shell** shell a command" CR +" **quit** exit phpdbg" CR CR + +"Type **help ** or (**help alias**) to get detailed help on any of the above commands, " +"for example **help list** or **h l**. Note that help will also match partial commands if unique " +"(and list out options if not unique), so **help clea** will give help on the **clean** command, " +"but **help cl** will list the summary for **clean** and **clear**." CR CR + +"Type **help aliases** to show a full alias list, including any registered phpdginit functions" CR +"Type **help syntax** for a general introduction to the command syntax." CR +"Type **help options** for a list of phpdbg command line options." CR +"Type **help phpdbginit** to show how to customise the debugger environment." +}, +{"_phpdbginit", +"Phpdgb uses an debugger script file to initialize the debugger context. By default, phpdbg looks " +"for the file named **.phpdbginit** in the current working directory. This location can be " +"overridden on the command line using the **-i** switch (see **help options** for a more " +"details)." CR CR + +"Debugger scripts can also be executed using the **script** command." CR CR + +"A script file can contain a sequence of valid debugger commands, comments and embedded PHP code. " "Comment lines are prefixed by the **#** character. PHP code is delimited by the start and end " +"escape tags **<:** and **:>**." CR CR + +"**Examples**" CR CR +//********Need decent script example +}, + +{"_syntax", +"All **phpdbg** commands are case sensitive. Commands start with a keyword, and some keywords " +"(**break**, **info**, **set**, **print** and **list**) may include a subcommand keyword. All " +"keywords have a single letter alias (most lowercase, some uppercase) that may be used instead " +"of spelling out the keyword in full. Note that keywords cannot be abbreviated other than by " +"substitution by the alias." CR CR + +"Some commands take one or more optional arguments which are interpreted in the context of the " +"command. In some cases the format of the argument enables the secondard keyword to be omitted." CR CR + +"Type **help** for an overview of all commands and type **help ** to get detailed help " +"on any specific command." CR CR + +"**Valid Examples**" CR CR + +" $P quit" CR +" $P q" CR +" Quit the debugger" CR CR + +" $P eval $total[2]" CR +" $P E $total[2]" CR +" Evaluate and print the variable $total[2] in the current stack frame" CR +" " CR +" $P break lineno 200" CR +" $P b my_source.php:200" CR +" Break at line 200 in the current source and in file **my_source.php**. " CR CR + +" $P b A ClassX::get_args if $arg[0] == \"fred\"" CR +" $P b d 3" CR +" Break at ClassX::get_args() if $arg[0] == \"fred\" and delete breakpoint 3" CR CR + +"**Examples of invalid commands**" CR +" $P break line 23" CR +" The command keyword is **lineno**; **line** is not allowed" CR CR + +" $P NEXT" CR +" Commands are case sensitive. The keyword is **next**" CR CR + +" $P s on" CR +" **step** takes an integer argument **0** or **1**; on/off is not allowed." CR CR + +" $P #This is a comment" CR +" Comments introduced by the **#** character are only allowed in **phpdbginit** script files." +}, + +{"_ZZ_aliases", +"Note that aliases can be used for either command or sub-command keywords or both, so **info b** " +"is a synomyn for **info break** and **l func** for **list func**, etc." CR CR + +"Note that help will also accept any alias as a parameter and provide help on that command, for example **h p** will provide help on the print command." +}, + +{"_ZZ_duplicate", +"Parameter is not unique. For detailed help select help on one of the above commands." +}, + +{"back", +"Provide a formatted backtrace using the standard debug_backtrace() functionality. An optional " +"unsigned integer argument specifying the maximum number of frames to be traced; if omitted then " +"a complete backtrace is given." CR CR + +"**Examples**" CR CR +" $P back 5" CR +" $P t " CR +" " CR +"A backtrace can be executed at any time during execution." +}, + +{"break", +"Breakpoints can be set at a range of targets within the execution environment. Execution will " +"be paused if the program flow hits a breakpoint. The break target can be one of the following " +"types:" CR CR + +" **Target** **Alias** **Purpose**" CR +" **file** **F** specify breakpoint by file:line" CR +" **lineno** **l** specify breakpoint by line of currently executing file" CR +" **func** **f** specify breakpoint by global function name" CR +" **method** **m** specify breakpoint by class::method" CR +" **address** **a** specify breakpoint by address" CR +" **op** **O** specify breakpoint by opcode" CR +" **on** **o** specify breakpoint by condition" CR +" **at** **A** specify breakpoint by location and condition" CR +" **del** **d** delete breakpoint by breakpoint identifier number" CR CR + +"The syntax of the target argument is dependent on the target type and in the case of file, func " +"method, and address targets the target keyword or alias is optional and can be omitted." CR CR + +"**Break on** takes a string argument which must be a valid PHP expression." CR CR + +"**Break at** takes two arguments. The first is any valid target as per the file, lineno, func " +"and address types. The second is a valid PHP expression which will trigger the break in " +"execution, if evaluated as true in a boolean context at the specified target." CR CR + +"Note that breakpoints can also be temporarily enabled and disabled by the set break command." CR CR + +"**Examples**" CR CR +" $P break file test.php:100" CR +" $P b F test.php:100" CR +" $P b test.php:100" CR +" Break execution at line 100 of test.php" CR CR + +" $P break lineno 200" CR +" $P b l 200" CR +" $P b 200" CR +" Break execution at line 200 of the currently PHP script file" CR CR + +" $P break func \\\\mynamespace\\\\my_function" CR +" $P b f \\\\mynamespace\\\\my_function" CR +" $P b \\\\mynamespace\\\\my_function" CR +" Break execution on entry to \\\\mynamespace\\\\my_function" CR CR + +" $P break method classX::method" CR +" $P b m classX::method" CR +" $P b classX::method" CR +" Break execution on entry to classX::method" CR CR + +" $P break address 0x7ff68f570e08" CR +" $P b a 0x7ff68f570e08" CR +" $P b 0x7ff68f570e08" CR +" Break at the opline at the address 0x7ff68f570e08" CR CR + +" $P break address my_function#14" CR +" $P b a my_function#14" CR +" $P b my_function#14" CR +" Break at the opline #14 of the function my_function" CR CR + +" $P break address \\\\my\\\\class::method#2" CR +" $P b a \\\\my\\\\class::method#2" CR +" $P b \\\\my\\\\class::method#2" CR +" Break at the opline #2 of the method \\\\my\\\\class::method" CR CR + +" $P break address test.php#3" CR +" $P b a test.php#3" CR +" Break at the opline #3 of test.php" CR CR + +" $P break on $cnt > 10" CR +" $P b o $cnt > 10" CR +" Break when the condition ($cnt > 10) evaluates to true" CR CR + +" $P break at phpdbg::isGreat if $opt == 'S'" CR +" Break at any opcode in phpdbg::isGreat when the condition ($opt == 'S') is true" CR CR + +" $P break at test.php:20 if !isset($x)" CR +" Break at every opcode on line 20 of test.php when the condition evaluates to true" CR CR + +" $P break op ZEND_ADD" CR +" $P b O ZEND_ADD" CR +" Break on any occurence of the opcode ZEND_ADD" CR CR + +" $P break del 2" CR +" $P b d 2" CR +" Remove breakpoint 2" CR CR + +"Note: Conditional breaks are costly in terms of runtime overhead. Use them only when required " +"as they significantly slow execution." CR CR + +"Note: An address is only valid for the current compilation." +}, + +{"clean", +"Classes, constants or functions can only be declared once in PHP. You may experience errors " +"during a debug session if you attempt to recompile a PHP source. The clean command clears " +"the Zend runtime tables which holds the sets of compiled classes, constants and functions, " +"releasing any associated storage back into the storage pool. This enables recompilation to " +"take place." CR CR + +"Note that you cannot selectively trim any of these resource pools. You can only do a complete " +"clean." +}, + +{"clear", +"Clearing breakpoints means you can once again run code without interruption." CR CR + +"Note: use break delete N to clear a specific breakpoint." CR CR + +"Note: if all breakpoints are cleared, then the PHP script will run until normal completion." +}, + +{"compile", +"The execution context can be pre-compiled before execution, to provide the opportunity to " +"inspect the generated opcode output. The execution context must be defined before the compile " +"command can be used. Use the command **exec** to set the execution context." CR CR + +"**Examples**" CR CR +" $P compile" CR +" $P c" CR CR + +"Note: Then that it is usually necessary to issue a **clean** command to reset the environment prior " +"to compilation." +}, +//********** Needs rewriting -- don't like -- careful thought -- what happens if you evaluate a function during execution, with and without breakpoints, with and without stepping ?? + +{"eval", +"The **eval** command takes a string expression which it evaluates and then displays. Note that " +"**eval** allows assignments and other write statements, thus enabling you to change the " +"environment during execution, so care is needed here." CR CR + +"**Examples**" CR CR +" $P eval $variable" CR +" $P E $variable" CR +" Will print_r($variable) on the console, if it is defined" CR CR + +" $P eval $variable = \"Hello phpdbg :)\"" CR +" $P E $variable = \"Hello phpdbg :)\"" CR +" Will set $variable in the current scope" CR CR + +"Note: **eval** will evaluate in the lowest (that is the executing) frame, unless this has first " +"been explicitly changed by issuing a **frame** command. " CR CR + +"Note: **eval** will always show the result; do not prefix the code with **return**" +}, + +{"exec", +"The **exec** command sets the execution context, that is the script to be executed." CR + +"The execution context must be defined either by executing the **exec** command or by using the " +"**-e** command line option before the script can be compiled or run." CR CR + +"Note that the **exec** command also can be used to replace a previously defined execution " +"context." CR CR + +"**Examples**" CR CR + +" $P exec /tmp/script.php" CR +" $P e /tmp/script.php" CR +" Set the execution context to **/tmp/script.php**" +}, + +//*********** Does F skip any breakpoints lower stack frames or only the current?? +{"finish", +"The **finish** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered within the current stack frame will be skipped. Execution " +"will then continue until the next breakpoint after leaving the stack frame or unitil " +"completion of the script" CR CR + +"Note **finish** will trigger a \"not executing\" error if not executing." +}, + +{"frame", +"The **frame** takes an optional integer argument. If omitted, then the current frame is displayed " +"If specified then the current scope is set to the corresponding frame listed in a **back** trace. " "This can be used to allowing access to the variables in a higher stack frame than that currently " +"being executed." CR CR + +"**Examples**" CR CR +" $P frame 2" CR +" $P E $count" CR +" Go to frame 2 and print out variable **$count** in that frame" CR CR + +"Note that this frame scope is discarded when execution continues, with the execution frame " +"then reset to the lowest executiong frame." +}, + +{"info", +"**info** commands provide quick access to various types of information about the PHP environment" CR +"Specific info commands are show below:" CR CR + +" **Target** **Alias** **Purpose**" CR +" **break** **b** show current breakpoints" CR +" **files** **F** show included files" CR +" **classes** **c** show loaded classes" CR +" **funcs** **f** show loaded classes" CR +" **error** **e** show last error" CR +" **vars** **v** show active variables" CR +" **literal** **l** show active literal constants" CR +" **memory** **m** show memory manager stats" +}, + +// ******** same issue about breakpoints in called frames +{"leave", +"The **leave** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered within the current stack frame will be skipped. In effect a " +"temporary breakpoint is associated with any return opcode, so that a break in execution occurs " +"before leaving the current stack frame. This allows inspection / modification of any frame " +"variables including the return value before it is returned" CR CR + +"**Examples**" CR CR + +" $P leave" CR +" $P L" CR CR +}, + +{"list", +"The list command displays source code for the given argument. The target type is specficied by " +"a second subcommand keyword:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **lines** **l** List N lines from the current execution point" CR +" **func** **f** List the complete source for a specified function" CR +" **method** **m** List the complete source for a specified class::method" CR +" **class** **c** List the complete source for a specified class" CR CR + +"Note that the context of **lines**, **func** and **method** can be determined by parsing the " +"argument, so these subcommands are optional. However, you must specify the **class** keyword " +"to list off a class." CR CR + +"**Examples**" CR CR +" $P list 2" CR +" $P l l 2" CR +" List the next 2 lines from the current file" CR CR + +" $P list my_function" CR +" $P l f my_function" CR +" List the source of the function **my_function**" CR CR + +//************ ???? +" $P list func .mine" CR +" $P l f .mine" CR +" List the source of the method **mine** from the active class in scope" CR CR + +" $P list m my::method" CR +" $P l my::method" CR +" List the source of **my::method**" CR CR + +" $P list c myClass" CR +" $P l c myClass" CR +" List the source of **myClass**" CR CR + +"Note that functions and classes can only be listed if the corresponding classes and functions " +"table in the Zend executor has a corresponding entry. You can use the compile command to " +"populate these tables for a given execution context." +}, + +//*********** what is the difference between n and s ??? +{"next", +"The **next** command causes control to be passed back to the vm, continuing execution. The next " +"opline will be executed if **step 1** is set. Otherwise execution will continue to the next " +"breakpoint or script completion" CR CR + +"Note **next** will trigger a \"not running\" error if not executing." +}, + +{"print", +"By default, print will show information about the current execution context." CR +"Other printing commands give access to instruction information." CR +"Specific printers loaded are show below:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **exec** **e** print out the instructions in the execution context" CR +" **opline** **o** print out the instruction in the current opline" CR +" **class** **c** print out the instructions in the specified class" CR +" **method** **m** print out the instructions in the specified method" CR +" **func** **f** print out the instructions in the specified function" CR +" **stack** **s** print out the instructions in the current stack" CR CR + +"**Examples**" CR CR +" $P print class \\\\my\\\\class" CR +" $P p c \\\\my\\\\class" CR +" Print the instructions for the methods in \\\\my\\\\class" CR CR + +" $P print method \\\\my\\\\class::method" CR +" $P p m \\\\my\\\\class::method" CR +" Print the instructions for \\\\my\\\\class::method" CR CR + +" $P print func .getSomething" CR +" $P p f .getSomething" CR +//************* Check this local method scope +" Print the instructions for ::getSomething in the active scope" CR CR + +" $P print func my_function" CR +" $P p f my_function" CR +" Print the instructions for the global function my_function" CR CR + +" $P print opline" CR +" $P p o" CR +" Print the instruction for the current opline" CR CR + +" $P print exec" CR +" $P p e" CR +" Print the instructions for the execution context" CR CR + +" $P print stack" CR +" $P p s" CR +" Print the instructions for the current stack" +}, + +{"quiet", +"Setting quietness on will stop the OPLINE output during execution" CR CR + +"**Examples**" CR CR +" $P quiet 1" CR +" $P Q 1" CR +" Will silence OPLINE output, while" CR CR + +" $P quiet 0" CR +" $P Q 0" CR +" Will enable OPLINE output again" CR CR + +"Note: Quietness is disabled automatically while stepping" +}, + +{"register", +//******* Needs a general explanation of the how registered functions work +"Register any global function for use as a command in phpdbg console" CR CR + +"**Examples**" CR CR +" $P register scandir" CR +" $P R scandir" CR +" Will register the scandir function for use in phpdbg" CR CR + +"Note: arguments passed as strings, return (if present) print_r'd on console" +}, + +{"run", +"Enter the vm, startinging execution. Execution will then continue until the next breakpoint " +"or completion of the script" +"**Examples**" CR CR +" $P run" CR +" $P r" CR +" Will cause execution of the context, if it is set." CR CR + +"Note that the execution context must be set. If not previously compiled, then the script will " +"be compiled before execution." CR CR + +"Note that attempting to run a script that is already executing will result in an \"execution " +"in progress\" error." +}, + +{"set", +"The **set** command is used to configure how phpdbg looks and behaves. Specific set commands " +"are as follows:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **prompt** **p** set the prompt " CR +" **color** **c** set color " CR +" **colors** **C** set colors on or off" CR +" **oplog** **O** set oplog output" CR +" **break** **b** set break **id** " CR CR + +"Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, " +"**cyan** and **black**. All colours except **none** can be followed by an optional " +"**-bold** or **-underline** qualifier." CR CR + +"Color elements can be one of **prompt**, **notice**, or **error**." CR CR + +"**Examples**" CR CR +" $P s C on" CR +" Set colors on" CR CR + +" $P set p >" CR +" $P set color prompt white-bold" CR +" Set the prompt to a bold >" CR CR + +" $P s c error red-bold" CR +" Use red bold for errors" CR +" " CR +" $P s b 4 off" CR +" Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR +//*********** check oplog syntax +}, + +{"shell", +//************ Check ! notation +"Direct access to shell commands saves having to switch windows/consoles" CR CR + +"**Examples**" CR CR +" $P shell ls /usr/src/php-src" CR +" $P - ls /usr/src/php-src" CR +" Will execute ls /usr/src/php-src, displaying the output in the console" +//*********** what does this mean????Note: read only commands please! +}, + +{"source", +"Sourcing a **phpdbginit** script during your debugging session might save some time." CR CR + +"The source command can also be used to export breakpoints to a phpdbginit file." CR CR + +"**Examples**" CR CR + +" $P source /my/init" CR +" $P . /my/init" CR +" Will execute the phpdbginit file at /my/init" CR CR + +" $P source export /my/init" CR +" $P . export /my/init" CR +" Will export breakpoints to /my/init in phpdbginit file format" +}, + +{"step", +"You can enable and disable **stepping** mode at the phpdbg prompt during execution. When " +"stepping mode is enabled, execution will be step through opcode by opcode." CR CR + +"**Examples**" CR CR +" $P step 1" CR +" $P s 1" CR +" Will enable stepping" CR CR + +"While stepping is enabled you are presented with an interactive prompt after the execution of each opcode" +}, + +{"until", +//******* More explanation needed -- how does until play with step 1 ?? +"The **until** command causes control to be passed back to the vm, continuing execution. Any " +"breakpoints that are encountered before the the next source line will be skipped. Execution " +"will then continue until the next breakpoint or completion of the script" CR CR + +"Note **until** will trigger a \"not executing\" error if not executing." + +}, +{"|", NULL /* end of table marker */} +}; /* }}} */ diff --git a/phpdbg_help.h b/phpdbg_help.h index 319142cb5b2..16a1e771e37 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -30,63 +30,19 @@ /** * Helper Forward Declarations */ -PHPDBG_HELP(exec); -PHPDBG_HELP(compile); -PHPDBG_HELP(step); -PHPDBG_HELP(next); -PHPDBG_HELP(run); -PHPDBG_HELP(eval); -PHPDBG_HELP(until); -PHPDBG_HELP(finish); -PHPDBG_HELP(leave); -PHPDBG_HELP(print); -PHPDBG_HELP(break); -PHPDBG_HELP(clean); -PHPDBG_HELP(clear); -PHPDBG_HELP(info); -PHPDBG_HELP(back); -PHPDBG_HELP(frame); -PHPDBG_HELP(quiet); -PHPDBG_HELP(list); -PHPDBG_HELP(set); -PHPDBG_HELP(register); -PHPDBG_HELP(options); -PHPDBG_HELP(source); -PHPDBG_HELP(shell); +PHPDBG_HELP(aliases); -/** - * Commands - */ -static const phpdbg_command_t phpdbg_help_commands[] = { - PHPDBG_COMMAND_D_EX(exec, "the execution context should be a valid path", 'e', help_exec, NULL, 0), - PHPDBG_COMMAND_D_EX(compile, "allow inspection of code before execution", 'c', help_compile, NULL, 0), - PHPDBG_COMMAND_D_EX(step, "step through execution to break at every opcode", 's', help_step, NULL, 0), - PHPDBG_COMMAND_D_EX(next, "continue executing while stepping or after breaking", 'n', help_next, NULL, 0), - PHPDBG_COMMAND_D_EX(run, "execute inside the phpdbg vm", 'r', help_run, NULL, 0), - PHPDBG_COMMAND_D_EX(eval, "access to eval() allows affecting the environment", 'E', help_eval, NULL, 0), - PHPDBG_COMMAND_D_EX(until, "continue until the current line is executed", 'u', help_until, NULL, 0), - PHPDBG_COMMAND_D_EX(finish, "continue until the current function has returned", 'F', help_finish, NULL, 0), - PHPDBG_COMMAND_D_EX(leave, "continue until the current function is returning", 'L', help_leave, NULL, 0), - PHPDBG_COMMAND_D_EX(print, "print context information or instructions", 'p', help_print, NULL, 0), - PHPDBG_COMMAND_D_EX(break, "breakpoints allow execution interruption", 'b', help_break, NULL, 0), - PHPDBG_COMMAND_D_EX(clean, "resetting the environment is useful while debugging", 'X', help_clean, NULL, 0), - PHPDBG_COMMAND_D_EX(clear, "reset breakpoints to execute without interruption", 'c', help_clear, NULL, 0), - PHPDBG_COMMAND_D_EX(info, "quick access to useful information on the console", 'i', help_info, NULL, 0), - PHPDBG_COMMAND_D_EX(back, "show debug backtrace information during execution", 't', help_back, NULL, 0), - PHPDBG_COMMAND_D_EX(frame, "switch to a frame in the current stack for inspection", 'f', help_frame, NULL, 0), - PHPDBG_COMMAND_D_EX(quiet, "be quiet during execution", 'Q', help_quiet, NULL, 0), - PHPDBG_COMMAND_D_EX(list, "list code gives you quick access to code", 'l', help_list, NULL, 0), - PHPDBG_COMMAND_D_EX(set, "configure how phpdbg looks and behaves", 'S', help_set, NULL, 0), - PHPDBG_COMMAND_D_EX(register, "register a function for use as a command", 'R', help_register,NULL, 0), - PHPDBG_COMMAND_D_EX(options, "show information about command line options", 'o', help_options, NULL, 0), - PHPDBG_COMMAND_D_EX(source, "load a phpdbginit file at the console", '.', help_source, NULL, 0), - PHPDBG_COMMAND_D_EX(shell, "execute system commands with direct shell access", '-', help_shell, NULL, 0), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_help_commands[]; #define phpdbg_help_header() \ phpdbg_notice("Welcome to phpdbg, the interactive PHP debugger, v%s", PHPDBG_VERSION); #define phpdbg_help_footer() \ phpdbg_notice("Please report bugs to <%s>", PHPDBG_ISSUES); +typedef struct _phpdbg_help_text_t { + char *key; + char *text; +} phpdbg_help_text_t; + +extern phpdbg_help_text_t phpdbg_help_text[]; #endif /* PHPDBG_HELP_H */ diff --git a/phpdbg_info.c b/phpdbg_info.c index 0f4233bf30c..b559b75835f 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -26,6 +26,18 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +const phpdbg_command_t phpdbg_info_commands[] = { + PHPDBG_COMMAND_D_EX(break, "show breakpoints", 'b', info_break, NULL, 0), + PHPDBG_COMMAND_D_EX(files, "show included files", 'F', info_files, NULL, 0), + PHPDBG_COMMAND_D_EX(classes, "show loaded classes", 'c', info_classes, NULL, 0), + PHPDBG_COMMAND_D_EX(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), + PHPDBG_COMMAND_D_EX(error, "show last error", 'e', info_error, NULL, 0), + PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_COMMAND_D_EX(literal, "show active literal constants", 'l', info_literal, NULL, 0), + PHPDBG_COMMAND_D_EX(memory, "show memory manager stats", 'm', info_memory, NULL, 0), + PHPDBG_END_COMMAND +}; + PHPDBG_INFO(break) /* {{{ */ { phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC); diff --git a/phpdbg_info.h b/phpdbg_info.h index a6b4e3719fe..c36e6bebd65 100644 --- a/phpdbg_info.h +++ b/phpdbg_info.h @@ -34,16 +34,6 @@ PHPDBG_INFO(vars); PHPDBG_INFO(literal); PHPDBG_INFO(memory); -static const phpdbg_command_t phpdbg_info_commands[] = { - PHPDBG_COMMAND_D_EX(break, "show breakpoints", 'b', info_break, NULL, 0), - PHPDBG_COMMAND_D_EX(files, "show included files", 'F', info_files, NULL, 0), - PHPDBG_COMMAND_D_EX(classes, "show loaded classes", 'c', info_classes, NULL, 0), - PHPDBG_COMMAND_D_EX(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), - PHPDBG_COMMAND_D_EX(error, "show last error", 'e', info_error, NULL, 0), - PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0), - PHPDBG_COMMAND_D_EX(literal, "show active literal constants", 'l', info_literal, NULL, 0), - PHPDBG_COMMAND_D_EX(memory, "show memory manager stats", 'm', info_memory, NULL, 0), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_info_commands[]; #endif /* PHPDBG_INFO_H */ diff --git a/phpdbg_list.c b/phpdbg_list.c index eb1091550b0..7177def8d62 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -32,6 +32,14 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +const phpdbg_command_t phpdbg_list_commands[] = { + PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, 1), + PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, 1), + PHPDBG_END_COMMAND +}; + PHPDBG_LIST(lines) /* {{{ */ { if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) { diff --git a/phpdbg_list.h b/phpdbg_list.h index f9d1885eaf2..14905f65673 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -36,12 +36,6 @@ void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC); void phpdbg_list_function(const zend_function* TSRMLS_DC); void phpdbg_list_file(const char*, long, long, int TSRMLS_DC); -static const phpdbg_command_t phpdbg_list_commands[] = { - PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, 1), - PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, 1), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_list_commands[]; #endif /* PHPDBG_LIST_H */ diff --git a/phpdbg_print.c b/phpdbg_print.c index c4925fe5fd7..5e3129ad7fb 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -26,6 +26,16 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +const phpdbg_command_t phpdbg_print_commands[] = { + PHPDBG_COMMAND_D_EX(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), + PHPDBG_COMMAND_D_EX(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), + PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, 1), + PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, 1), + PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, 1), + PHPDBG_COMMAND_D_EX(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), + PHPDBG_END_COMMAND +}; + PHPDBG_PRINT(opline) /* {{{ */ { if (EG(in_execution) && EG(current_execute_data)) { diff --git a/phpdbg_print.h b/phpdbg_print.h index 80010d5e7cc..ed85e965c1b 100644 --- a/phpdbg_print.h +++ b/phpdbg_print.h @@ -35,17 +35,6 @@ PHPDBG_PRINT(method); PHPDBG_PRINT(func); PHPDBG_PRINT(stack); -/** - * Commands - */ -static const phpdbg_command_t phpdbg_print_commands[] = { - PHPDBG_COMMAND_D_EX(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), - PHPDBG_COMMAND_D_EX(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), - PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, 1), - PHPDBG_COMMAND_D_EX(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_print_commands[]; #endif /* PHPDBG_PRINT_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 529ab04194d..447d40896bd 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -57,7 +57,6 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 2), PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1), - PHPDBG_COMMAND_D(aliases, "show alias list", 'a', NULL, 0), PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, 1), PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, 1), PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), @@ -908,76 +907,6 @@ PHPDBG_COMMAND(clear) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(aliases) /* {{{ */ -{ - const phpdbg_command_t *prompt_command = phpdbg_prompt_commands; - - phpdbg_help_header(); - phpdbg_writeln("Below are the aliased, short versions of all supported commands"); - while (prompt_command && prompt_command->name) { - if (prompt_command->alias) { - if (prompt_command->subs) { - const phpdbg_command_t *sub_command = prompt_command->subs; - phpdbg_writeln(EMPTY); - phpdbg_writeln(" %c -> %9s", prompt_command->alias, prompt_command->name); - while (sub_command && sub_command->name) { - if (sub_command->alias) { - phpdbg_writeln(" |-------- %c -> %15s\t%s", sub_command->alias, - sub_command->name, sub_command->tip); - } - ++sub_command; - } - phpdbg_writeln(EMPTY); - } else { - phpdbg_writeln(" %c -> %9s\t\t\t%s", prompt_command->alias, - prompt_command->name, prompt_command->tip); - } - } - - ++prompt_command; - } - phpdbg_help_footer(); - - return SUCCESS; -} /* }}} */ - -PHPDBG_COMMAND(help) /* {{{ */ -{ - switch (param->type) { - case EMPTY_PARAM: { - const phpdbg_command_t *prompt_command = phpdbg_prompt_commands; - const phpdbg_command_t *help_command = phpdbg_help_commands; - - phpdbg_help_header(); - phpdbg_writeln("To get help regarding a specific command type \"help command\""); - - phpdbg_notice("Commands"); - - while (prompt_command && prompt_command->name) { - phpdbg_writeln( - " %10s\t%s", prompt_command->name, prompt_command->tip); - ++prompt_command; - } - - phpdbg_notice("Help Commands"); - - while (help_command && help_command->name) { - phpdbg_writeln(" %10s\t%s", help_command->name, help_command->tip); - ++help_command; - } - - phpdbg_help_footer(); - } break; - - default: { - phpdbg_error( - "No help can be found for the subject \"%s\"", param->str); - } - } - - return SUCCESS; -} /* }}} */ - PHPDBG_COMMAND(quiet) /* {{{ */ { switch (param->type) { diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 6807d88f41d..e66ea16dce3 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -48,7 +48,6 @@ PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clear); PHPDBG_COMMAND(help); PHPDBG_COMMAND(quiet); -PHPDBG_COMMAND(aliases); PHPDBG_COMMAND(shell); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); diff --git a/phpdbg_set.c b/phpdbg_set.c index 7c4da12a46e..50c07b66d85 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -26,6 +26,17 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +const phpdbg_command_t phpdbg_set_commands[] = { + PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, 0), +#ifndef _WIN32 + PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, 1), + PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, 1), +#endif + PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, 0), + PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, 0), + PHPDBG_END_COMMAND +}; + PHPDBG_SET(prompt) /* {{{ */ { switch (param->type) { diff --git a/phpdbg_set.h b/phpdbg_set.h index 120aeb34f4e..ddc3876f5dc 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -33,15 +33,6 @@ PHPDBG_SET(colors); PHPDBG_SET(oplog); PHPDBG_SET(break); -static const phpdbg_command_t phpdbg_set_commands[] = { - PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, 0), -#ifndef _WIN32 - PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, 1), - PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, 1), -#endif - PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, 0), - PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, 0), - PHPDBG_END_COMMAND -}; +extern const phpdbg_command_t phpdbg_set_commands[]; #endif /* PHPDBG_SET_H */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 1effcfccaf9..4bb671247ed 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -30,6 +30,8 @@ #ifdef _WIN32 # include "win32/time.h" +#elif defined(HAVE_SYS_IOCTL_H) +# include "sys/ioctl.h" #endif ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -385,3 +387,22 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ return PHPDBG_G(prompt)[1]; } /* }}} */ + +PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ +{ + int columns; +#ifdef _win32 + CONSOLE_SCREEN_BUFFER_INFO csbi; + + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); + columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; +#elif defined(HAVE_SYS_IOCTL_H) + struct winsize w; + + columns = ioctl(fileno(stdout), TIOCGWINSZ, &w) == 0 ? w.ws_col : 100; +#else + columns = 100; +#endif + return columns; +} /* }}} */ + diff --git a/phpdbg_utils.h b/phpdbg_utils.h index c5164c3ac31..ee7ff3f5bd1 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -107,4 +107,7 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); /* }}} */ PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC); PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */ +/* {{{ Console Width */ +PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D); /* }}} */ + #endif /* PHPDBG_UTILS_H */ From ebdfef807a39e1c6156c85fcfccc72f1fa69aa8e Mon Sep 17 00:00:00 2001 From: Terry Ellison Date: Wed, 5 Feb 2014 00:04:21 +0000 Subject: [PATCH 032/137] Update help content and refactor new routine in php_help.c * I've added more content to the help to expand desciption for new-to-phpdbg developers. * After a code review of the new routines that I've added to the help module, I've decided that the implementation was unnecessarily convolved and that Keep-It-Simple-Stupid would be more understandable, maintainable and have no material performance hit. --- phpdbg.c | 8 +- phpdbg_bp.c | 6 +- phpdbg_help.c | 446 ++++++++++++++++++++++++++------------------------ 3 files changed, 243 insertions(+), 217 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 179424bf943..2f9348a7692 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -614,10 +614,10 @@ const char phpdbg_ini_hardcoded[] = /* overwriteable ini defaults must be set in phpdbg_ini_defaults() */ #define INI_DEFAULT(name, value) \ - Z_SET_REFCOUNT(tmp, 0); \ - Z_UNSET_ISREF(tmp); \ - ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \ - zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL); + Z_SET_REFCOUNT(tmp, 0); \ + Z_UNSET_ISREF(tmp); \ + ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \ + zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL); void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */ { diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 511d1db57d7..1e85f039a51 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -324,9 +324,9 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char PHPDBG_BREAK_MAPPING(new_break.id, class_table); } else { phpdbg_notice("Breakpoint exists at %s::%s", class_name, func_name); - } + } - efree(lcname); + efree(lcname); } /* }}} */ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */ @@ -992,7 +992,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { zval *retval = NULL; int orig_interactive = CG(interactive); zval **orig_retval = EG(return_value_ptr_ptr); diff --git a/phpdbg_help.c b/phpdbg_help.c index ec0af2ac79d..c73c644c09d 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -22,12 +22,6 @@ #include "phpdbg.h" #include "phpdbg_help.h" #include "phpdbg_prompt.h" -#include "phpdbg_print.h" -#include "phpdbg_utils.h" -#include "phpdbg_break.h" -#include "phpdbg_list.h" -#include "phpdbg_info.h" -#include "phpdbg_set.h" #include "zend.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -45,8 +39,9 @@ const phpdbg_command_t phpdbg_help_commands[] = { PHPDBG_END_COMMAND }; /* }}} */ -/* {{{ pretty_format. Takes a text string, expands any formatting escapes and wrap the text */ -static char *pretty_format(char *text TSRMLS_DC) { +/* {{{ pretty_print. Formatting escapes and wrapping text in a string before printing it. */ +void pretty_print(char *text TSRMLS_DC) +{ char *new, *p, *q; const char *prompt_escape = phpdbg_get_prompt(TSRMLS_C); @@ -64,7 +59,7 @@ static char *pretty_format(char *text TSRMLS_DC) { char *last_new_blank = NULL; /* position in new buffer of last blank char */ unsigned int last_blank_count = 0; /* printable char offset of last blank char */ - unsigned int line_count = 0; /* number printable chars on current line */ + unsigned int line_count = 0; /* number printable chars on current line */ /* First pass calculates a safe size for the pretty print version */ for (p = text; *p; p++) { @@ -85,12 +80,12 @@ static char *pretty_format(char *text TSRMLS_DC) { * Second pass substitutes the bold and prompt escape sequences and line wrap * * ** toggles bold on and off if PHPDBG_IS_COLOURED flag is set - * $P substitutes the prompt sequence - * Lines are wrapped by replacing the last blank with a CR before - * characters. (This defaults to 100 if the width can't be detected). In the - * pathelogical case where no blanks are found, then the wrap occurs at the - * first blank. - */ + * $P substitutes the prompt sequence + * Lines are wrapped by replacing the last blank with a CR before + * characters. (This defaults to 100 if the width can't be detected). In the + * pathelogical case where no blanks are found, then the wrap occurs at the + * first blank. + */ for (p = text, q = new; *p; p++) { if ( UNEXPECTED(*p == ' ') ) { last_new_blank = q; @@ -102,7 +97,7 @@ static char *pretty_format(char *text TSRMLS_DC) { last_blank_count = 0; line_count = 0; } else if ( UNEXPECTED(p[0] == '*') && p[1] == '*' ) { - if (bold_escape_len) { + if (bold_escape_len) { in_bold = !in_bold; memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); q += bold_escape_len; @@ -133,136 +128,136 @@ static char *pretty_format(char *text TSRMLS_DC) { *q++ = '\0'; if ((q-new)>size) { - phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); + phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); } - return new; + + (void) phpdbg_write("%s\n", new); + efree(new); } /* }}} */ +/* {{{ summary_print. Print a summary line giving, the command, its alias and tip */ +void summary_print(phpdbg_command_t const * const cmd TSRMLS_DC) +{ + char *summary; + spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", + cmd->name, cmd->alias, cmd->tip); + pretty_print(summary TSRMLS_CC); + efree(summary); +} + /* {{{ get_help. Retries and formats text from the phpdbg help text table */ -static char *get_help(const char * const key TSRMLS_DC) { - phpdbg_help_text_t *p = phpdbg_help_text; +static char *get_help(const char * const key TSRMLS_DC) +{ + phpdbg_help_text_t *p; - /* note that phpdbg_help_text is collated in key order */ - for( ;p->key[0]key[0]==key[0]) { - if (!strcmp(p->key+1, key+1)) { + for (p = phpdbg_help_text; p->key; p++) { + if (!strcmp(p->key, key)) { return p->text; } - p++; } - return estrdup(""); /* return empty string to denote no match found */ + return ""; /* return empty string to denote no match found */ } /* }}} */ -/* {{{ get_command. Return one or more matching commands from a command table. +/* {{{ get_command. Return number of matching commands from a command table. * Unlike the command parser, the help search is sloppy that is partial matches can occur - * * Any single character key is taken as an alias and only an exact match is allowed + * * Any single character key is taken as an alias. * * Other keys are matched again the table on the first len characters. - * * This means that non-unique keys can generate multiple matches - * * The command summary is an emalloced string containing one line for each match - * * The function only returns a command entry if a unique match occurs. - * - * The rationale here is to assist users in finding help on commands. So "h fr" will - * generate a summary line for "help frame" and return the frame record. But "h cl" will - * generate two summary records for the "clear" and "clean" and a NULL command record. + * * This means that non-unique keys can generate multiple matches. + * * The first matching command is returned as an OUT parameter. * + * The rationale here is to assist users in finding help on commands. So unique matches + * will be used to generate a help message but non-unique one will be used to list alternatives. */ -#define ALIAS_FMT "Command: **%s** Alias: **%c** **%s**\n" -static const phpdbg_command_t *get_command( - const char *key, size_t len, /* pointer and length of key */ - char **command_summary, /* address of command summary text */ - const phpdbg_command_t * const commands /* command table to be scanned */ - TSRMLS_DC) { - const phpdbg_command_t *c, *c_found; +static int get_command( + const char *key, size_t len, /* pointer and length of key */ + phpdbg_command_t const **command, /* address of first matching command */ + phpdbg_command_t const * const commands /* command table to be scanned */ + TSRMLS_DC) +{ + const phpdbg_command_t *c; unsigned int num_matches = 0; - char *summary; if (len == 1) { for (c=commands; c->name; c++) { if (c->alias == key[0]) { num_matches++; - if (command_summary) { - spprintf(&summary, 0, ALIAS_FMT, c->name, c->alias, c->tip); + if ( num_matches == 1 && command) { + *command = c; } - c_found = c; - break; } } } else { for (c=commands; c->name; c++) { if (!strncmp(c->name, key, len)) { ++num_matches; - c_found = c; - if (command_summary) { - if (num_matches == 1) { - spprintf(&summary, 0, ALIAS_FMT, c->name, c->alias, c->tip); - } else { /* num_matches > 1 */ - /* very rare so "keep it simple" string concat of summaries */ - char *tmp = summary; - spprintf(&summary, 0, "%s" ALIAS_FMT, tmp, c->name, c->alias, c->tip); - efree(tmp); - } + if ( num_matches == 1 && command) { + *command = c; } } } } - if (command_summary) { - *command_summary = (num_matches > 0) ? summary : NULL; - } - return (num_matches == 1) ? c_found : NULL; /* NULL return denotes no single match found */ + return num_matches; -} /* }}} */ +} /* }}} */ PHPDBG_COMMAND(help) /* {{{ */ { - char *banner, *help_text, *pretty_banner, *pretty_help_text; - const phpdbg_command_t *cmd; + phpdbg_command_t const *cmd; + int n; if (param->type == EMPTY_PARAM) { - char * help_text = pretty_format(get_help("_overview" TSRMLS_CC) TSRMLS_CC); - phpdbg_write("\n%s\n", help_text); - efree(help_text); + pretty_print(get_help("overview!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; } if (param->type == STR_PARAM) { - cmd = get_command( param->str, param->len, &banner, phpdbg_prompt_commands TSRMLS_CC); + n = get_command( param->str, param->len, &cmd, phpdbg_prompt_commands TSRMLS_CC); - if (banner) { - pretty_banner = pretty_format(banner TSRMLS_CC); - help_text = get_help((cmd ? cmd->name : "_ZZ_duplicate") TSRMLS_CC); - pretty_help_text = pretty_format(help_text TSRMLS_CC); - phpdbg_write("%s\n%s\n", pretty_banner, pretty_help_text); - efree(banner); - efree(pretty_banner); - efree(pretty_help_text); + if (n==1) { + summary_print(cmd TSRMLS_CC); + pretty_print(get_help(cmd->name TSRMLS_CC) TSRMLS_CC); return SUCCESS; - } else if (param->type == STR_PARAM) { - cmd = get_command( param->str, param->len, NULL, phpdbg_help_commands TSRMLS_CC); - if (cmd) { - char *name; - spprintf(&name, cmd->name_len+2, "_%s", cmd->name); - help_text = get_help(name TSRMLS_CC); - pretty_help_text = pretty_format(help_text TSRMLS_CC); - phpdbg_write("%s\n", pretty_help_text); - efree(pretty_help_text); - efree(name); + } else if (n>1) { + if (param->len > 1) { + for (cmd=phpdbg_prompt_commands; cmd->name; cmd++) { + if (!strncmp(cmd->name, param->str, param->len)) { + summary_print(cmd TSRMLS_CC); + } + } + pretty_print(get_help("duplicate!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; + } else { + phpdbg_error("Internal help error, non-unique alias \"%c\"", param->str[0]); + return FAILURE; + } + + } else { /* no prompt command found so try help topic */ + n = get_command( param->str, param->len, &cmd, phpdbg_help_commands TSRMLS_CC); + + if (n>0) { + if (cmd->alias == 'a') { /* help aliases executes a canned routine */ + return cmd->handler(param, NULL TSRMLS_CC); + } else { + pretty_print(get_help(cmd->name TSRMLS_CC) TSRMLS_CC); + return SUCCESS; + } } } } - + phpdbg_error("No help can be found for the subject \"%s\"", param->str); return FAILURE; - } /* }}} */ PHPDBG_HELP(aliases) /* {{{ */ { const phpdbg_command_t *c, *c_sub; - char *help_text; int len; /* Print out aliases for all commands except help as this one comes last */ @@ -274,48 +269,99 @@ PHPDBG_HELP(aliases) /* {{{ */ len = 20 - 1 - c->name_len; for(c_sub = c->subs; c_sub->alias; c_sub++) { if (c_sub->alias) { - phpdbg_writeln(" %c %c %s %-*s %s", + phpdbg_writeln(" %c %c %s %-*s %s", c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); } } - phpdbg_writeln(EMPTY); } } } /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ - c = get_command( "h", 1, NULL, phpdbg_prompt_commands TSRMLS_CC); + (void) get_command( "h", 1, & c, phpdbg_prompt_commands TSRMLS_CC); +/* In function ‘phpdbg_do_help_aliases’: +274:2: warning: passing argument 3 of ‘get_command’ from incompatible pointer type [enabled by default] +180:12: note: expected ‘struct phpdbg_command_t **’ but argument is of type ‘const struct phpdbg_command_t **’ */ phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip); + len = 20 - 1 - c->name_len; for(c_sub = c->subs; c_sub->alias; c_sub++) { if (c_sub->alias) { - phpdbg_writeln(" %c %c %s %-*s %s", + phpdbg_writeln(" %c %c %s %-*s %s", c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); } } - help_text = pretty_format(get_help("_ZZ_aliases" TSRMLS_CC) TSRMLS_CC); - phpdbg_write("\n%s\n", help_text); - efree(help_text); + pretty_print(get_help("aliases!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; } /* }}} */ -/* {{{ Help Text Table +/* {{{ Help Text Table * Contains help text entries keyed by a lowercase ascii key. * Text is in ascii and enriched by a simple markup: * ** toggles bold font emphasis. * $P insert an bold phpdbg> prompt. - * \ escapes the following character. Note that this is itself escaped inside string + * \ escapes the following character. Note that this is itself escaped inside string * constants so \\\\ is required to output a single \ e.g. as in namespace names. * * Text will be wrapped according to the STDOUT terminal width, so paragraphs are - * flowed using the C stringizing and the CR definition. Also note that entries + * flowed using the C stringizing and the CR definition. Also note that entries * are collated in alphabetic order on key. - */ + * + * Also note the convention that help text not directly referenceable as a help param + * has a key ending in ! + */ #define CR "\n" phpdbg_help_text_t phpdbg_help_text[] = { -{"_options", + +/******************************** General Help Topics ********************************/ +{"overview!", CR +"**phpdbg** is a lightweight, powerful and easy to use debugging platform for PHP5.4+" CR +"It supports the following commands:" CR CR + +"**Information**" CR +" **list** list PHP source" CR +" **info** displays information on the debug session" CR +" **help** provide help on a topic" CR +" **print** print argument " CR +" **frame** select a stack frame and print a stack frame summary" CR CR + +"**Compilation**" CR +" **compile** compile a PHP source" CR CR + +"**Starting and Stopping Execution**" CR +" **exec** set execution context" CR +" **clean** clean the execution environment" CR +" **run** attempt execution" CR +" **eval** evaluate some code" CR +" **step** Enable or disable per opcode stepping mode" CR +" **next** continue execution" CR +" **until** continue execution up to the given location" CR +" **finish** continue up to end of the current execution frame" CR +" **leave** continue up to end of the current execution frame and halt after the calling instruction" CR +" **break** set a breakpoint at the specified target" CR +" **clear** clear one or all breakpoints" CR CR + +"**Miscellaneous**" CR +" **quiet** silence some output" CR +" **set** set the phpdbg configuration" CR +" **source** execute a phpdbginit script" CR +" **register** register a phpdbginit function as a command alias" CR +" **shell** shell a command" CR +" **quit** exit phpdbg" CR CR + +"Type **help ** or (**help alias**) to get detailed help on any of the above commands, " +"for example **help list** or **h l**. Note that help will also match partial commands if unique " +"(and list out options if not unique), so **help clea** will give help on the **clean** command, " +"but **help cl** will list the summary for **clean** and **clear**." CR CR + +"Type **help aliases** to show a full alias list, including any registered phpdginit functions" CR +"Type **help syntax** for a general introduction to the command syntax." CR +"Type **help options** for a list of phpdbg command line options." CR +"Type **help phpdbginit** to show how to customise the debugger environment." +}, +{"options", CR "Below are the command line options supported by phpdbg" CR CR /* note the extra 4 space index in because of the extra **** */ "**Command Line Options and Flags**" CR @@ -349,54 +395,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { "interface/port." CR CR "Specify both stdin and stdout with -lstdin/stdout; by default stdout is stdin * 2." -}, +}, -{"_overview", -"**phpdbg** is a lightweight, powerful and easy to use debugging platform for PHP5.4+" CR -"It supports the following commands:" CR CR - -"**Information**" CR -" **list** list PHP source" CR -" **info** displays information on the debug session" CR -" **help** provide help on a topic" CR -" **print** print argument " CR -" **frame** select a stack frame and print a stack frame summary" CR CR - -"**Compilation**" CR -" **compile** compile a PHP source" CR CR - -"**Starting and Stopping Execution**" CR -" **exec** set execution context" CR -" **clean** clean the execution environment" CR -" **run** attempt execution" CR -" **eval** evaluate some code" CR -" **stepping** Enable or disable per opcode stepping mode" CR -" **next** continue execution" CR -" **until** continue execution up to the given location" CR -" **finish** continue up to end of the current execution frame" CR -" **leave** continue up to end of the current execution frame and halt after the calling instruction" CR -" **break** set a breakpoint at the specified target" CR -" **clear** clear one or all breakpoints" CR CR - -"**Miscellaneous**" CR -" **quiet** silence some output" CR -" **set** set the phpdbg configuration" CR -" **source** execute a phpdbginit script" CR -" **register** register a phpdbginit function as a command alias" CR -" **shell** shell a command" CR -" **quit** exit phpdbg" CR CR - -"Type **help ** or (**help alias**) to get detailed help on any of the above commands, " -"for example **help list** or **h l**. Note that help will also match partial commands if unique " -"(and list out options if not unique), so **help clea** will give help on the **clean** command, " -"but **help cl** will list the summary for **clean** and **clear**." CR CR - -"Type **help aliases** to show a full alias list, including any registered phpdginit functions" CR -"Type **help syntax** for a general introduction to the command syntax." CR -"Type **help options** for a list of phpdbg command line options." CR -"Type **help phpdbginit** to show how to customise the debugger environment." -}, -{"_phpdbginit", +{"phpdbginit", CR "Phpdgb uses an debugger script file to initialize the debugger context. By default, phpdbg looks " "for the file named **.phpdbginit** in the current working directory. This location can be " "overridden on the command line using the **-i** switch (see **help options** for a more " @@ -404,14 +405,21 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Debugger scripts can also be executed using the **script** command." CR CR -"A script file can contain a sequence of valid debugger commands, comments and embedded PHP code. " "Comment lines are prefixed by the **#** character. PHP code is delimited by the start and end " -"escape tags **<:** and **:>**." CR CR +"A script file can contain a sequence of valid debugger commands, comments and embedded PHP " +"code. " CR CR -"**Examples**" CR CR -//********Need decent script example -}, +"Comment lines are prefixed by the **#** character. Note that comments are only allowed in script " +"files and not in interactive sessions." CR CR -{"_syntax", +"PHP code is delimited by the start and end escape tags **<:** and **:>**. PHP code can be used " +"to define application context for a debugging session and also to extend the debugger by defining " +"and **register** PHP functions as new commands." CR CR + +"Also note that executing a **clear** command will cause the current **phpdbginit** to be reparsed " +"/ reloaded." +}, + +{"syntax", CR "All **phpdbg** commands are case sensitive. Commands start with a keyword, and some keywords " "(**break**, **info**, **set**, **print** and **list**) may include a subcommand keyword. All " "keywords have a single letter alias (most lowercase, some uppercase) that may be used instead " @@ -420,7 +428,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Some commands take one or more optional arguments which are interpreted in the context of the " "command. In some cases the format of the argument enables the secondard keyword to be omitted." CR CR - + "Type **help** for an overview of all commands and type **help ** to get detailed help " "on any specific command." CR CR @@ -454,20 +462,22 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P #This is a comment" CR " Comments introduced by the **#** character are only allowed in **phpdbginit** script files." -}, +}, -{"_ZZ_aliases", +/******************************** Help Codicils ********************************/ +{"aliases!", CR "Note that aliases can be used for either command or sub-command keywords or both, so **info b** " "is a synomyn for **info break** and **l func** for **list func**, etc." CR CR "Note that help will also accept any alias as a parameter and provide help on that command, for example **h p** will provide help on the print command." -}, +}, -{"_ZZ_duplicate", +{"duplicate!", CR "Parameter is not unique. For detailed help select help on one of the above commands." -}, +}, -{"back", +/******************************** Help on Commands ********************************/ +{"back", "Provide a formatted backtrace using the standard debug_backtrace() functionality. An optional " "unsigned integer argument specifying the maximum number of frames to be traced; if omitted then " "a complete backtrace is given." CR CR @@ -479,7 +489,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "A backtrace can be executed at any time during execution." }, -{"break", +{"break", "Breakpoints can be set at a range of targets within the execution environment. Execution will " "be paused if the program flow hits a breakpoint. The break target can be one of the following " "types:" CR CR @@ -568,9 +578,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { "as they significantly slow execution." CR CR "Note: An address is only valid for the current compilation." -}, +}, -{"clean", +{"clean", "Classes, constants or functions can only be declared once in PHP. You may experience errors " "during a debug session if you attempt to recompile a PHP source. The clean command clears " "the Zend runtime tables which holds the sets of compiled classes, constants and functions, " @@ -579,18 +589,18 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note that you cannot selectively trim any of these resource pools. You can only do a complete " "clean." -}, +}, -{"clear", +{"clear", "Clearing breakpoints means you can once again run code without interruption." CR CR "Note: use break delete N to clear a specific breakpoint." CR CR "Note: if all breakpoints are cleared, then the PHP script will run until normal completion." -}, +}, -{"compile", -"The execution context can be pre-compiled before execution, to provide the opportunity to " +{"compile", +"The execution context may be pre-compiled before execution to provide an opportunity to " "inspect the generated opcode output. The execution context must be defined before the compile " "command can be used. Use the command **exec** to set the execution context." CR CR @@ -600,13 +610,12 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note: Then that it is usually necessary to issue a **clean** command to reset the environment prior " "to compilation." -}, -//********** Needs rewriting -- don't like -- careful thought -- what happens if you evaluate a function during execution, with and without breakpoints, with and without stepping ?? +}, -{"eval", -"The **eval** command takes a string expression which it evaluates and then displays. Note that " -"**eval** allows assignments and other write statements, thus enabling you to change the " -"environment during execution, so care is needed here." CR CR +{"eval", +"The **eval** command takes a string expression which it evaluates and then displays. It " +"evaluates in the context of the lowest (that is the executing) frame, unless this has first " +"been explicitly changed by issuing a **frame** command. " CR CR "**Examples**" CR CR " $P eval $variable" CR @@ -617,39 +626,42 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P E $variable = \"Hello phpdbg :)\"" CR " Will set $variable in the current scope" CR CR -"Note: **eval** will evaluate in the lowest (that is the executing) frame, unless this has first " -"been explicitly changed by issuing a **frame** command. " CR CR +"Note that **eval** allows any valid PHP expression including assignments, function calls and " +"other write statements. This enables you to change the environment during execution, so care " +"is needed here. You can even call PHP functions which have breakpoints defined. " CR CR -"Note: **eval** will always show the result; do not prefix the code with **return**" -}, +"Note: **eval** will always show the result, so do not prefix the code with **return**" +}, -{"exec", -"The **exec** command sets the execution context, that is the script to be executed." CR - -"The execution context must be defined either by executing the **exec** command or by using the " +{"exec", +"The **exec** command sets the execution context, that is the script to be executed. The " +"execution context must be defined either by executing the **exec** command or by using the " "**-e** command line option before the script can be compiled or run." CR CR "Note that the **exec** command also can be used to replace a previously defined execution " -"context." CR CR +"context." CR CR "**Examples**" CR CR " $P exec /tmp/script.php" CR " $P e /tmp/script.php" CR " Set the execution context to **/tmp/script.php**" -}, +}, //*********** Does F skip any breakpoints lower stack frames or only the current?? -{"finish", +{"finish", "The **finish** command causes control to be passed back to the vm, continuing execution. Any " "breakpoints that are encountered within the current stack frame will be skipped. Execution " "will then continue until the next breakpoint after leaving the stack frame or unitil " "completion of the script" CR CR -"Note **finish** will trigger a \"not executing\" error if not executing." -}, +"Note when **step**ping is enabled, any opcode steps within the current stack frame are also " +"skipped. "CR CR -{"frame", +"Note **finish** will trigger a \"not executing\" error if not executing." +}, + +{"frame", "The **frame** takes an optional integer argument. If omitted, then the current frame is displayed " "If specified then the current scope is set to the corresponding frame listed in a **back** trace. " "This can be used to allowing access to the variables in a higher stack frame than that currently " "being executed." CR CR @@ -661,9 +673,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note that this frame scope is discarded when execution continues, with the execution frame " "then reset to the lowest executiong frame." -}, +}, -{"info", +{"info", "**info** commands provide quick access to various types of information about the PHP environment" CR "Specific info commands are show below:" CR CR @@ -679,9 +691,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, // ******** same issue about breakpoints in called frames -{"leave", +{"leave", "The **leave** command causes control to be passed back to the vm, continuing execution. Any " -"breakpoints that are encountered within the current stack frame will be skipped. In effect a " +"breakpoints that are encountered within the current stack frame will be skipped. In effect a " "temporary breakpoint is associated with any return opcode, so that a break in execution occurs " "before leaving the current stack frame. This allows inspection / modification of any frame " "variables including the return value before it is returned" CR CR @@ -690,9 +702,14 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P leave" CR " $P L" CR CR -}, -{"list", +"Note when **step**ping is enabled, any opcode steps within the current stack frame are also " +"skipped. "CR CR + +"Note **leave** will trigger a \"not executing\" error if not executing." +}, + +{"list", "The list command displays source code for the given argument. The target type is specficied by " "a second subcommand keyword:" CR CR @@ -734,13 +751,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, //*********** what is the difference between n and s ??? -{"next", +{"next", "The **next** command causes control to be passed back to the vm, continuing execution. The next " "opline will be executed if **step 1** is set. Otherwise execution will continue to the next " "breakpoint or script completion" CR CR "Note **next** will trigger a \"not running\" error if not executing." -}, +}, {"print", "By default, print will show information about the current execution context." CR @@ -786,7 +803,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Print the instructions for the current stack" }, -{"quiet", +{"quiet", "Setting quietness on will stop the OPLINE output during execution" CR CR "**Examples**" CR CR @@ -801,7 +818,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note: Quietness is disabled automatically while stepping" }, -{"register", +{"register", //******* Needs a general explanation of the how registered functions work "Register any global function for use as a command in phpdbg console" CR CR @@ -813,7 +830,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note: arguments passed as strings, return (if present) print_r'd on console" }, -{"run", +{"run", "Enter the vm, startinging execution. Execution will then continue until the next breakpoint " "or completion of the script" "**Examples**" CR CR @@ -828,7 +845,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "in progress\" error." }, -{"set", +{"set", "The **set** command is used to configure how phpdbg looks and behaves. Specific set commands " "are as follows:" CR CR @@ -859,9 +876,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P s b 4 off" CR " Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR //*********** check oplog syntax -}, +}, -{"shell", +{"shell", //************ Check ! notation "Direct access to shell commands saves having to switch windows/consoles" CR CR @@ -870,9 +887,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P - ls /usr/src/php-src" CR " Will execute ls /usr/src/php-src, displaying the output in the console" //*********** what does this mean????Note: read only commands please! -}, +}, -{"source", +{"source", "Sourcing a **phpdbginit** script during your debugging session might save some time." CR CR "The source command can also be used to export breakpoints to a phpdbginit file." CR CR @@ -897,17 +914,26 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P s 1" CR " Will enable stepping" CR CR -"While stepping is enabled you are presented with an interactive prompt after the execution of each opcode" +"While stepping is enabled you are presented with an interactive prompt after the execution of " +"each opcode." CR CR + +"Note that when executing the **finish** and **leave** commands, and oplines within the current " +"execution frame will be skipped in line with the command behaviour. Stepping will resume on exit " +"from the current frame." }, -{"until", -//******* More explanation needed -- how does until play with step 1 ?? +{"until", "The **until** command causes control to be passed back to the vm, continuing execution. Any " -"breakpoints that are encountered before the the next source line will be skipped. Execution " +"breakpoints that are encountered before the next source line will be skipped. Execution " "will then continue until the next breakpoint or completion of the script" CR CR +"Note when **step**ping is enabled, any opcode steps within the current line are also skipped. "CR CR + +"Note that if the next line is **not** executed then **all** subsequent breakpoints will be " +"skipped. " CR CR + "Note **until** will trigger a \"not executing\" error if not executing." }, -{"|", NULL /* end of table marker */} +{NULL, NULL /* end of table marker */} }; /* }}} */ From b0273e749ca09b6c89dc44e5f33ed6ac788f7a40 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 6 Feb 2014 20:43:17 +0100 Subject: [PATCH 033/137] Fix issue 68 (made check win only) --- phpdbg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 6cb1645e65a..fa14b6687d3 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -887,17 +887,17 @@ phpdbg_main: bp_tmp_file = NULL; } } + + if (!bp_tmp_file) { + phpdbg_error("Unable to create temporary file"); + return 1; + } #else if (!mkstemp(bp_tmp_file)) { memset(bp_tmp_file, 0, sizeof(bp_tmp_file)); } #endif - if (!bp_tmp_file) { - phpdbg_error( - "Unable to create temporary file"); - return 1; - } } ini_entries = NULL; ini_entries_len = 0; From 21c973d3de5d0b3d3ce8377dfdd07bd3940d72d1 Mon Sep 17 00:00:00 2001 From: Terry Ellison Date: Sun, 9 Feb 2014 15:04:13 +0000 Subject: [PATCH 034/137] More update to help text on parameter typing --- phpdbg_help.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index c73c644c09d..a085b2aa3dd 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -420,14 +420,24 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, {"syntax", CR -"All **phpdbg** commands are case sensitive. Commands start with a keyword, and some keywords " -"(**break**, **info**, **set**, **print** and **list**) may include a subcommand keyword. All " -"keywords have a single letter alias (most lowercase, some uppercase) that may be used instead " -"of spelling out the keyword in full. Note that keywords cannot be abbreviated other than by " -"substitution by the alias." CR CR +"All **phpdbg** commands are case sensitive. Commands start with a keyword, and some (**break**, " +"**info**, **set**, **print** and **list**) may include a subcommand keyword. All keywords are " +"lower case but also have a single letter alias that may be used as an alternative to typing in the" +"keyword in full. Note some aliases are uppercase, and that keywords cannot be abbreviated other " +"than by substitution by the alias." CR CR -"Some commands take one or more optional arguments which are interpreted in the context of the " -"command. In some cases the format of the argument enables the secondard keyword to be omitted." CR CR +"Some commands take an argument. Arguments are typed according to their format:" CR +" * **omitted**" CR +" * **address** **0x** followed by a hex string" CR +" * **number** an optionally signed number" CR +" * **method** a valid **Class::methodName** expression" CR +" * **func#op** a valid **Function name** follow by # and an integer" CR +" * **method#op** a valid **Class::methodName** follow by # and an integer" CR +" * **string** a general string" CR +" * **function** a valid **Function name**" CR +" * **File-line** a valid **filename** follow by : and an integer" CR CR + +"In some cases the type of the argument enables the second keyword to be omitted." CR CR "Type **help** for an overview of all commands and type **help ** to get detailed help " "on any specific command." CR CR @@ -505,8 +515,8 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **at** **A** specify breakpoint by location and condition" CR " **del** **d** delete breakpoint by breakpoint identifier number" CR CR -"The syntax of the target argument is dependent on the target type and in the case of file, func " -"method, and address targets the target keyword or alias is optional and can be omitted." CR CR +"The syntax of the target argument is dependent on the target type and in the case of address, " +"file, func, line and method targets the target keyword or alias is optional and can be omitted." CR CR "**Break on** takes a string argument which must be a valid PHP expression." CR CR @@ -514,7 +524,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "and address types. The second is a valid PHP expression which will trigger the break in " "execution, if evaluated as true in a boolean context at the specified target." CR CR -"Note that breakpoints can also be temporarily enabled and disabled by the set break command." CR CR +"Note that breakpoints can also be disabled and re-enabled by the **set break** command." CR CR "**Examples**" CR CR " $P break file test.php:100" CR @@ -863,23 +873,22 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Color elements can be one of **prompt**, **notice**, or **error**." CR CR "**Examples**" CR CR -" $P s C on" CR +" $P S C on" CR " Set colors on" CR CR " $P set p >" CR " $P set color prompt white-bold" CR " Set the prompt to a bold >" CR CR -" $P s c error red-bold" CR +" $P S c error red-bold" CR " Use red bold for errors" CR " " CR -" $P s b 4 off" CR +" $P S b 4 off" CR " Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR //*********** check oplog syntax }, {"shell", -//************ Check ! notation "Direct access to shell commands saves having to switch windows/consoles" CR CR "**Examples**" CR CR From 0dc1072a190c10f0ee1be67103549c1ec79436ea Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 13 Feb 2014 20:42:54 +0100 Subject: [PATCH 035/137] Fix issue 72 (too much whitespace in config.m4) --- config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.m4 b/config.m4 index 3ad53ba8979..c48a5db60fc 100644 --- a/config.m4 +++ b/config.m4 @@ -6,7 +6,7 @@ PHP_ARG_ENABLE(phpdbg, for phpdbg support, [ --enable-phpdbg Build phpdbg], yes, yes) PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build, -[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) +[ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) if test "$PHP_PHPDBG" != "no"; then AC_DEFINE(HAVE_PHPDBG, 1, [ ]) From 5778e010b7a5db3229d925c6a93c88f6dc78bc9e Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 15 Feb 2014 04:52:04 +0000 Subject: [PATCH 036/137] have a go at writing lexer for input --- phpdbg_lexer.l | 89 ++++++++++++++++++++++++++++++ phpdbg_parser.y | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 phpdbg_lexer.l create mode 100644 phpdbg_parser.y diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l new file mode 100644 index 00000000000..eb93d130f06 --- /dev/null +++ b/phpdbg_lexer.l @@ -0,0 +1,89 @@ +%{ + +/* + * phpdbg_lexer.l + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#define YYSTYPE phpdbg_param_t + +#include "phpdbg_parser.h" +#include +#include +%} + +%option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h" +%option warn nodefault + +%option reentrant noyywrap never-interactive nounistd +%option bison-bridge + +C_TRUE "true" +C_YES "yes" +C_ON "on" +C_ENABLED "enabled" +C_FALSE "false" +C_NO "no" +C_OFF "off" +C_DISABLED "disabled" + +DIGITS [0-9]+ +ID [a-zA-Z][a-zA-Z0-9_]+ +METHOD {ID}::{ID} +FILE [^ :0-9]{1,}:[0-9]+ +OPLINE 0x[a-fA-F0-9]+ +LITERAL \"(\\.|[^\\"])*\" +WS [ \r\n\t]+ +%% + +{WS} { } +{C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { + yylval->type = NUMERIC_PARAM; + yylval->num = 1; + return C_TRUTHY; +} +{C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} { + yylval->type = NUMERIC_PARAM; + yylval->num = 0; + return C_FALSY; +} +{DIGITS} { + yylval->type = NUMERIC_PARAM; + yylval->num = atoi(yytext); + return T_DIGITS; +} +{METHOD} { + yylval->type = METHOD_PARAM; + yylval->method.class = "class"; + yylval->method.name = "func"; + return T_METHOD; +} +{FILE} { + yylval->type = FILE_PARAM; + yylval->file.name = strndup(yytext, yyleng); + yylval->file.line = 0; + return T_FILE; +} +{OPLINE} { + yylval->type = ADDR_PARAM; + yylval->addr = strtoul(yytext, NULL, 10); + return T_OPLINE; +} +{LITERAL} { + yylval->type = STR_PARAM; + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_LITERAL; +} +[a-zA-Z]+ { + yylval->type = STR_PARAM; + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + + return C_CMD; +} +. { + /** command detection here **/ +} +%% diff --git a/phpdbg_parser.y b/phpdbg_parser.y new file mode 100644 index 00000000000..ef3dca58bb6 --- /dev/null +++ b/phpdbg_parser.y @@ -0,0 +1,140 @@ +%error-verbose +%{ + +/* + * phpdbg_parser.y + * + * flex phpdb_lexer.l + * bison phpdbg_parser.y + * gcc -g -o parser phpdbg_lexer.c phpdbg_parser.c -I/usr/src/php-src/main -I/usr/src/php-src/Zend -I/usr/src/php-src/TSRM -I/usr/src/php-src + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" + +#define YYSTYPE phpdbg_param_t + +void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { + if (param && param->type) { + switch (param->type) { + case STR_PARAM: + fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); + break; + + case ADDR_PARAM: + fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); + break; + + case FILE_PARAM: + fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); + break; + + case METHOD_PARAM: + fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_PARAM: + fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); + break; + } + } +} + +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +int yyerror(phpdbg_param_t **param, yyscan_t scanner, const char *msg) { + fprintf(stderr, "Parse Error: %s\n", msg); +} + +int main(int argc, char **argv) { + do { + phpdbg_param_t *expression; + yyscan_t scanner; + YY_BUFFER_STATE state; + char buffer[8096]; + size_t buflen = 0L; + + if (fgets(&buffer[0], 8096, stdin) != NULL) { + if (yylex_init(&scanner)) { + // couldn't initialize + fprintf(stderr, "could not initialize scanner\n"); + return 1; + } + + state = yy_scan_string(buffer, scanner); + + if (yyparse(&expression, scanner) <= 0) { + // error parsing + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); + } else fprintf(stderr, "could not parse input (%s) !!\n", buffer); + } else fprintf(stderr, "could not get input !!\n"); + } while (1); + + return 0; +} +%} + +%code requires { +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif +} + +%output "phpdbg_parser.c" +%defines "phpdbg_parser.h" + +%define api.pure +%lex-param { yyscan_t scanner } +%parse-param { phpdbg_param_t **expression } +%parse-param { yyscan_t scanner } + +%token C_CMD "command (possibly automatically detected)" + +%token C_TRUTHY "truthy (true, on, yes or enabled)" +%token C_FALSY "falsy (false, off, no or disabled)" +%token C_STRING "string (some input, perhaps)" + +%token T_DIGITS "digits (numbers)" +%token T_LITERAL "literal (T_LITERAL)" +%token T_METHOD "method (T_METHOD)" +%token T_OPLINE "opline (T_OPLINE)" +%token T_FILE "file (T_FILE)" +%token T_ID "identifier (T_ID)" + +%% + +input + : handler {} + ; + +parameters + : parameters parameter { phpdbg_debug_param(&$2, "got another parameter"); } + | parameter { phpdbg_debug_param(&$1, "got first parameter"); } + ; + +params + : /* empty */ { /* do nothing */ } + | parameters { $$ = $1; } + ; + +command + : C_CMD { fprintf(stderr, "got cmd: %s\n", $1.str); } + | C_CMD C_CMD { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); } + ; + +parameter + : T_DIGITS { $$ = $1; } + | T_FILE { $$ = $1; } + | T_METHOD { $$ = $1; } + | T_OPLINE { $$ = $1; } + | T_ID { $$ = $1; } + | T_LITERAL { $$ = $1; } + ; + +handler + : command params {} + ; +%% From a01853de7890a3058a79666d1359b63b729d586a Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 15 Feb 2014 19:51:39 +0000 Subject: [PATCH 037/137] betterness --- phpdbg_lexer.l | 105 +++++++++++++++++++++++++++++------------------- phpdbg_parser.y | 17 +++++--- 2 files changed, 74 insertions(+), 48 deletions(-) diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index eb93d130f06..73998c3d994 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -13,6 +13,8 @@ #include %} +%s RAW + %option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h" %option warn nodefault @@ -27,6 +29,8 @@ C_FALSE "false" C_NO "no" C_OFF "off" C_DISABLED "disabled" +C_EVAL "eval" +C_SHELL "shell" DIGITS [0-9]+ ID [a-zA-Z][a-zA-Z0-9_]+ @@ -35,53 +39,70 @@ FILE [^ :0-9]{1,}:[0-9]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ +INPUT [^\n]+ %% - -{WS} { } -{C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { - yylval->type = NUMERIC_PARAM; - yylval->num = 1; - return C_TRUTHY; +{WS} { } + +{ + {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { + yylval->type = NUMERIC_PARAM; + yylval->num = 1; + return C_TRUTHY; + } + {C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} { + yylval->type = NUMERIC_PARAM; + yylval->num = 0; + return C_FALSY; + } + {C_EVAL} { + BEGIN(RAW); + return C_EVAL; + } + {C_SHELL} { + BEGIN(RAW); + return C_SHELL; + } + {DIGITS} { + yylval->type = NUMERIC_PARAM; + yylval->num = atoi(yytext); + return T_DIGITS; + } + {METHOD} { + yylval->type = METHOD_PARAM; + yylval->method.class = "class"; + yylval->method.name = "func"; + return T_METHOD; + } + {FILE} { + yylval->type = FILE_PARAM; + yylval->file.name = strndup(yytext, yyleng); + yylval->file.line = 0; + return T_FILE; + } + {OPLINE} { + yylval->type = ADDR_PARAM; + yylval->addr = strtoul(yytext, NULL, 10); + return T_OPLINE; + } + {LITERAL} { + yylval->type = STR_PARAM; + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_LITERAL; + } + {ID} { + yylval->type = STR_PARAM; + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_ID; + } } -{C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} { - yylval->type = NUMERIC_PARAM; - yylval->num = 0; - return C_FALSY; -} -{DIGITS} { - yylval->type = NUMERIC_PARAM; - yylval->num = atoi(yytext); - return T_DIGITS; -} -{METHOD} { - yylval->type = METHOD_PARAM; - yylval->method.class = "class"; - yylval->method.name = "func"; - return T_METHOD; -} -{FILE} { - yylval->type = FILE_PARAM; - yylval->file.name = strndup(yytext, yyleng); - yylval->file.line = 0; - return T_FILE; -} -{OPLINE} { - yylval->type = ADDR_PARAM; - yylval->addr = strtoul(yytext, NULL, 10); - return T_OPLINE; -} -{LITERAL} { +{INPUT} { yylval->type = STR_PARAM; yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; - return T_LITERAL; -} -[a-zA-Z]+ { - yylval->type = STR_PARAM; - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - - return C_CMD; + BEGIN(INITIAL); + return T_INPUT; } . { /** command detection here **/ diff --git a/phpdbg_parser.y b/phpdbg_parser.y index ef3dca58bb6..fa53e7956f7 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -82,7 +82,7 @@ int main(int argc, char **argv) { typedef void* yyscan_t; #endif } - +%expect 1 %output "phpdbg_parser.c" %defines "phpdbg_parser.h" @@ -91,11 +91,11 @@ typedef void* yyscan_t; %parse-param { phpdbg_param_t **expression } %parse-param { yyscan_t scanner } -%token C_CMD "command (possibly automatically detected)" - %token C_TRUTHY "truthy (true, on, yes or enabled)" %token C_FALSY "falsy (false, off, no or disabled)" %token C_STRING "string (some input, perhaps)" +%token C_EVAL "eval" +%token C_SHELL "shell" %token T_DIGITS "digits (numbers)" %token T_LITERAL "literal (T_LITERAL)" @@ -103,7 +103,7 @@ typedef void* yyscan_t; %token T_OPLINE "opline (T_OPLINE)" %token T_FILE "file (T_FILE)" %token T_ID "identifier (T_ID)" - +%token T_INPUT "input (input string or data)" %% input @@ -121,8 +121,11 @@ params ; command - : C_CMD { fprintf(stderr, "got cmd: %s\n", $1.str); } - | C_CMD C_CMD { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); } + : T_ID { fprintf(stderr, "got cmd: %s\n", $1.str); } + | T_ID T_ID { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); } + /* exceptional cases below */ + | C_EVAL T_INPUT { fprintf(stderr, "got eval: %s\n", $2.str); } + | C_SHELL T_INPUT { fprintf(stderr, "got shell: %s\n", $2.str); } ; parameter @@ -132,6 +135,8 @@ parameter | T_OPLINE { $$ = $1; } | T_ID { $$ = $1; } | T_LITERAL { $$ = $1; } + | C_TRUTHY { $$ = $1; } + | C_FALSY { $$ = $1; } ; handler From cdf1dcc497e890119d03024ee097b687a9b785f8 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 15 Feb 2014 20:05:44 +0000 Subject: [PATCH 038/137] barf on unexpected input --- phpdbg_lexer.l | 6 ++---- phpdbg_parser.y | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 73998c3d994..6915ab62e04 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -41,7 +41,6 @@ LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ INPUT [^\n]+ %% -{WS} { } { {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { @@ -104,7 +103,6 @@ INPUT [^\n]+ BEGIN(INITIAL); return T_INPUT; } -. { - /** command detection here **/ -} +{WS} { /* ignore whitespace */ } +. { return T_UNEXPECTED; } %% diff --git a/phpdbg_parser.y b/phpdbg_parser.y index fa53e7956f7..9b87847ebc9 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -104,6 +104,7 @@ typedef void* yyscan_t; %token T_FILE "file (T_FILE)" %token T_ID "identifier (T_ID)" %token T_INPUT "input (input string or data)" +%token T_UNEXPECTED "unexpected input (input string or data)" %% input From a32f1b46540fd8add78f53cc8059f7f749ca3ab8 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 15 Feb 2014 22:53:20 +0000 Subject: [PATCH 039/137] handle strings better --- phpdbg_lexer.l | 39 ++++++++++++++++++++++++++++++--------- phpdbg_parser.y | 4 ++-- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 6915ab62e04..f916a0bc6aa 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -11,9 +11,21 @@ #include "phpdbg_parser.h" #include #include + +static inline void phpdbg_param_append(phpdbg_param_t *param, const char *next, size_t nlen) { + if (param->len + nlen > param->addr) { + param->str = realloc( + param->str, param->len + 1024); + param->addr += 1024; + } + memcpy(¶m->str[param->len], next, nlen); + param->len += nlen; + param->str[param->len] = 0; +} %} %s RAW +%s STRING %option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h" %option warn nodefault @@ -29,6 +41,7 @@ C_FALSE "false" C_NO "no" C_OFF "off" C_DISABLED "disabled" + C_EVAL "eval" C_SHELL "shell" @@ -37,7 +50,6 @@ ID [a-zA-Z][a-zA-Z0-9_]+ METHOD {ID}::{ID} FILE [^ :0-9]{1,}:[0-9]+ OPLINE 0x[a-fA-F0-9]+ -LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ INPUT [^\n]+ %% @@ -55,11 +67,11 @@ INPUT [^\n]+ } {C_EVAL} { BEGIN(RAW); - return C_EVAL; + return C_EVAL; } {C_SHELL} { BEGIN(RAW); - return C_SHELL; + return C_SHELL; } {DIGITS} { yylval->type = NUMERIC_PARAM; @@ -83,18 +95,27 @@ INPUT [^\n]+ yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } - {LITERAL} { - yylval->type = STR_PARAM; - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return T_LITERAL; - } {ID} { yylval->type = STR_PARAM; yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } + \" { + BEGIN(STRING); + yylval->type = STR_PARAM; + yylval->str = (char*) malloc(28); + yylval->len = 0; + yylval->addr = 28; + } + [^\\"\n]* { phpdbg_param_append(yylval, yytext); } + \\n { phpdbg_param_append(yylval, "\n"); } + \\t { phpdbg_param_append(yylval, "\t"); } + \\[\\"] { phpdbg_param_append(yylval, "\\"); } + \" { + BEGIN(INITIAL); + return T_STRING; + } } {INPUT} { yylval->type = STR_PARAM; diff --git a/phpdbg_parser.y b/phpdbg_parser.y index 9b87847ebc9..f8fc5a0a7d9 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -98,7 +98,7 @@ typedef void* yyscan_t; %token C_SHELL "shell" %token T_DIGITS "digits (numbers)" -%token T_LITERAL "literal (T_LITERAL)" +%token T_STRING "literal (T_LITERAL)" %token T_METHOD "method (T_METHOD)" %token T_OPLINE "opline (T_OPLINE)" %token T_FILE "file (T_FILE)" @@ -135,7 +135,7 @@ parameter | T_METHOD { $$ = $1; } | T_OPLINE { $$ = $1; } | T_ID { $$ = $1; } - | T_LITERAL { $$ = $1; } + | T_STRING { $$ = $1; } | C_TRUTHY { $$ = $1; } | C_FALSY { $$ = $1; } ; From 5f899346865bba0657015c4552fd5b90ebdb643e Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 15 Feb 2014 23:34:35 +0000 Subject: [PATCH 040/137] Revert "handle strings better" This reverts commit a32f1b46540fd8add78f53cc8059f7f749ca3ab8. --- phpdbg_lexer.l | 39 +++++++++------------------------------ phpdbg_parser.y | 4 ++-- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index f916a0bc6aa..6915ab62e04 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -11,21 +11,9 @@ #include "phpdbg_parser.h" #include #include - -static inline void phpdbg_param_append(phpdbg_param_t *param, const char *next, size_t nlen) { - if (param->len + nlen > param->addr) { - param->str = realloc( - param->str, param->len + 1024); - param->addr += 1024; - } - memcpy(¶m->str[param->len], next, nlen); - param->len += nlen; - param->str[param->len] = 0; -} %} %s RAW -%s STRING %option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h" %option warn nodefault @@ -41,7 +29,6 @@ C_FALSE "false" C_NO "no" C_OFF "off" C_DISABLED "disabled" - C_EVAL "eval" C_SHELL "shell" @@ -50,6 +37,7 @@ ID [a-zA-Z][a-zA-Z0-9_]+ METHOD {ID}::{ID} FILE [^ :0-9]{1,}:[0-9]+ OPLINE 0x[a-fA-F0-9]+ +LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ INPUT [^\n]+ %% @@ -67,11 +55,11 @@ INPUT [^\n]+ } {C_EVAL} { BEGIN(RAW); - return C_EVAL; + return C_EVAL; } {C_SHELL} { BEGIN(RAW); - return C_SHELL; + return C_SHELL; } {DIGITS} { yylval->type = NUMERIC_PARAM; @@ -95,27 +83,18 @@ INPUT [^\n]+ yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } + {LITERAL} { + yylval->type = STR_PARAM; + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_LITERAL; + } {ID} { yylval->type = STR_PARAM; yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } - \" { - BEGIN(STRING); - yylval->type = STR_PARAM; - yylval->str = (char*) malloc(28); - yylval->len = 0; - yylval->addr = 28; - } - [^\\"\n]* { phpdbg_param_append(yylval, yytext); } - \\n { phpdbg_param_append(yylval, "\n"); } - \\t { phpdbg_param_append(yylval, "\t"); } - \\[\\"] { phpdbg_param_append(yylval, "\\"); } - \" { - BEGIN(INITIAL); - return T_STRING; - } } {INPUT} { yylval->type = STR_PARAM; diff --git a/phpdbg_parser.y b/phpdbg_parser.y index f8fc5a0a7d9..9b87847ebc9 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -98,7 +98,7 @@ typedef void* yyscan_t; %token C_SHELL "shell" %token T_DIGITS "digits (numbers)" -%token T_STRING "literal (T_LITERAL)" +%token T_LITERAL "literal (T_LITERAL)" %token T_METHOD "method (T_METHOD)" %token T_OPLINE "opline (T_OPLINE)" %token T_FILE "file (T_FILE)" @@ -135,7 +135,7 @@ parameter | T_METHOD { $$ = $1; } | T_OPLINE { $$ = $1; } | T_ID { $$ = $1; } - | T_STRING { $$ = $1; } + | T_LITERAL { $$ = $1; } | C_TRUTHY { $$ = $1; } | C_FALSY { $$ = $1; } ; From f89f66d7620c316e751d5a3335a012070e7de457 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 16 Feb 2014 17:41:50 +0100 Subject: [PATCH 041/137] removed warning; WS --- phpdbg_bp.c | 2 +- phpdbg_help.c | 36 ++++++++++++++++-------------------- phpdbg_utils.c | 4 ++-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 1e85f039a51..609644548fa 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -992,7 +992,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position); zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { zval *retval = NULL; int orig_interactive = CG(interactive); zval **orig_retval = EG(return_value_ptr_ptr); diff --git a/phpdbg_help.c b/phpdbg_help.c index a085b2aa3dd..3aa82848e00 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -63,13 +63,13 @@ void pretty_print(char *text TSRMLS_DC) /* First pass calculates a safe size for the pretty print version */ for (p = text; *p; p++) { - if ( UNEXPECTED(p[0] == '*') && p[1] == '*' ) { + if (UNEXPECTED(p[0] == '*') && p[1] == '*') { size += bold_escape_len - 2; p++; - } else if ( UNEXPECTED(p[0] == '$') && p[1] == 'P' ) { + } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') { size += prompt_escape_len - 2; p++; - } else if ( UNEXPECTED(p[0] == '\\') ) { + } else if (UNEXPECTED(p[0] == '\\')) { p++; } } @@ -87,16 +87,16 @@ void pretty_print(char *text TSRMLS_DC) * first blank. */ for (p = text, q = new; *p; p++) { - if ( UNEXPECTED(*p == ' ') ) { + if (UNEXPECTED(*p == ' ')) { last_new_blank = q; last_blank_count = line_count++; *q++ = ' '; - } else if ( UNEXPECTED(*p == '\n') ) { + } else if (UNEXPECTED(*p == '\n')) { last_new_blank = NULL; *q++ = *p; last_blank_count = 0; line_count = 0; - } else if ( UNEXPECTED(p[0] == '*') && p[1] == '*' ) { + } else if (UNEXPECTED(p[0] == '*') && p[1] == '*') { if (bold_escape_len) { in_bold = !in_bold; memcpy (q, in_bold ? bold_on_escape : bold_off_escape, bold_escape_len); @@ -104,12 +104,12 @@ void pretty_print(char *text TSRMLS_DC) /* bold on/off has zero print width so line count is unchanged */ } p++; - } else if ( UNEXPECTED(p[0] == '$') && p[1] == 'P' ) { + } else if (UNEXPECTED(p[0] == '$') && p[1] == 'P') { memcpy (q, prompt_escape, prompt_escape_len); q += prompt_escape_len; line_count += prompt_len; p++; - } else if ( UNEXPECTED(p[0] == '\\') ) { + } else if (UNEXPECTED(p[0] == '\\')) { p++; *q++ = *p; line_count++; @@ -131,7 +131,7 @@ void pretty_print(char *text TSRMLS_DC) phpdbg_error("Output overrun of %lu bytes", ((q-new) - size)); } - (void) phpdbg_write("%s\n", new); + phpdbg_write("%s\n", new); efree(new); } /* }}} */ @@ -139,8 +139,7 @@ void pretty_print(char *text TSRMLS_DC) void summary_print(phpdbg_command_t const * const cmd TSRMLS_DC) { char *summary; - spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", - cmd->name, cmd->alias, cmd->tip); + spprintf(&summary, 0, "Command: **%s** Alias: **%c** **%s**\n", cmd->name, cmd->alias, cmd->tip); pretty_print(summary TSRMLS_CC); efree(summary); } @@ -172,10 +171,10 @@ static char *get_help(const char * const key TSRMLS_DC) * will be used to generate a help message but non-unique one will be used to list alternatives. */ static int get_command( - const char *key, size_t len, /* pointer and length of key */ - phpdbg_command_t const **command, /* address of first matching command */ - phpdbg_command_t const * const commands /* command table to be scanned */ - TSRMLS_DC) + const char *key, size_t len, /* pointer and length of key */ + phpdbg_command_t const **command, /* address of first matching command */ + phpdbg_command_t const * commands /* command table to be scanned */ + TSRMLS_DC) { const phpdbg_command_t *c; unsigned int num_matches = 0; @@ -270,7 +269,7 @@ PHPDBG_HELP(aliases) /* {{{ */ for(c_sub = c->subs; c_sub->alias; c_sub++) { if (c_sub->alias) { phpdbg_writeln(" %c %c %s %-*s %s", - c->alias, c_sub->alias, c->name, len, c_sub->name, c_sub->tip); + c->alias, c_sub->alias, (char *)c->name, len, c_sub->name, c_sub->tip); } } } @@ -278,10 +277,7 @@ PHPDBG_HELP(aliases) /* {{{ */ } /* Print out aliases for help as this one comes last, with the added text on how aliases are used */ - (void) get_command( "h", 1, & c, phpdbg_prompt_commands TSRMLS_CC); -/* In function ‘phpdbg_do_help_aliases’: -274:2: warning: passing argument 3 of ‘get_command’ from incompatible pointer type [enabled by default] -180:12: note: expected ‘struct phpdbg_command_t **’ but argument is of type ‘const struct phpdbg_command_t **’ */ + get_command("h", 1, &c, phpdbg_prompt_commands TSRMLS_CC); phpdbg_writeln(" %c %-20s %s\n", c->alias, c->name, c->tip); len = 20 - 1 - c->name_len; diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 4bb671247ed..d64d9ad6860 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -31,7 +31,7 @@ #ifdef _WIN32 # include "win32/time.h" #elif defined(HAVE_SYS_IOCTL_H) -# include "sys/ioctl.h" +# include "sys/ioctl.h" #endif ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -391,7 +391,7 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ PHPDBG_API int phpdbg_get_terminal_width(TSRMLS_D) /* {{{ */ { int columns; -#ifdef _win32 +#ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); From c744605dc7f313835fb7ba584f88c3138fa50782 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 19:25:15 +0000 Subject: [PATCH 042/137] build stack from command line --- phpdbg_cmd.h | 19 ++++++++++++-- phpdbg_lexer.l | 39 ++++++++++++++++----------- phpdbg_parser.y | 70 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index c86f92bb478..6eb4e73e904 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -53,7 +53,8 @@ struct _phpdbg_input_t { int argc; }; -typedef struct _phpdbg_param { +typedef struct _phpdbg_param phpdbg_param_t; +struct _phpdbg_param { phpdbg_param_type type; long num; zend_ulong addr; @@ -67,7 +68,21 @@ typedef struct _phpdbg_param { } method; char *str; size_t len; -} phpdbg_param_t; + phpdbg_param_t *next; +}; + +#define phpdbg_init_param(v, t) do{ \ + v->type = t; \ + v->addr = 0; \ + v->num = 0; \ + v->file.name = NULL; \ + v->file.line = 0; \ + v->method.class = NULL; \ + v->method.name = NULL; \ + v->str = NULL; \ + v->len = 0; \ + v->next = NULL; \ +} while(0) typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 6915ab62e04..3b6c9cae27e 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -44,65 +44,74 @@ INPUT [^\n]+ { {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { - yylval->type = NUMERIC_PARAM; + phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return C_TRUTHY; } {C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} { - yylval->type = NUMERIC_PARAM; + phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return C_FALSY; } - {C_EVAL} { + {C_EVAL} { BEGIN(RAW); - return C_EVAL; + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return C_EVAL; } {C_SHELL} { BEGIN(RAW); + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; return C_SHELL; } {DIGITS} { - yylval->type = NUMERIC_PARAM; + phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } {METHOD} { - yylval->type = METHOD_PARAM; + phpdbg_init_param(yylval, METHOD_PARAM); yylval->method.class = "class"; yylval->method.name = "func"; return T_METHOD; } {FILE} { - yylval->type = FILE_PARAM; + phpdbg_init_param(yylval, FILE_PARAM); yylval->file.name = strndup(yytext, yyleng); yylval->file.line = 0; return T_FILE; } {OPLINE} { - yylval->type = ADDR_PARAM; + phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } - {LITERAL} { - yylval->type = STR_PARAM; + {LITERAL} { + phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; return T_LITERAL; } - {ID} { - yylval->type = STR_PARAM; + {ID} { + phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; return T_ID; } } {INPUT} { - yylval->type = STR_PARAM; + phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; BEGIN(INITIAL); return T_INPUT; } -{WS} { /* ignore whitespace */ } -. { return T_UNEXPECTED; } +{WS} { /* ignore whitespace */ } +. { + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_UNEXPECTED; +} %% diff --git a/phpdbg_parser.y b/phpdbg_parser.y index 9b87847ebc9..dfc13a48e15 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -4,7 +4,7 @@ /* * phpdbg_parser.y * - * flex phpdb_lexer.l + * flex phpdbg_lexer.l * bison phpdbg_parser.y * gcc -g -o parser phpdbg_lexer.c phpdbg_parser.c -I/usr/src/php-src/main -I/usr/src/php-src/Zend -I/usr/src/php-src/TSRM -I/usr/src/php-src */ @@ -43,37 +43,64 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { #include "phpdbg_parser.h" #include "phpdbg_lexer.h" +static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { + phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); + + if (!next) + return; + + *(next) = *(param); + + if (stack->addr) { + next->next = + stack->next; + } else { + stack->addr = (ulong) next; + } + + stack->next = next; + stack->len++; +} + int yyerror(phpdbg_param_t **param, yyscan_t scanner, const char *msg) { fprintf(stderr, "Parse Error: %s\n", msg); } int main(int argc, char **argv) { do { - phpdbg_param_t *expression; yyscan_t scanner; YY_BUFFER_STATE state; char buffer[8096]; size_t buflen = 0L; + phpdbg_param_t *stack = malloc(sizeof(phpdbg_param_t)); + + phpdbg_init_param(stack, EMPTY_PARAM); if (fgets(&buffer[0], 8096, stdin) != NULL) { if (yylex_init(&scanner)) { - // couldn't initialize fprintf(stderr, "could not initialize scanner\n"); return 1; } state = yy_scan_string(buffer, scanner); - if (yyparse(&expression, scanner) <= 0) { - // error parsing + if (yyparse(&stack, scanner) <= 0) { + fprintf(stderr, "got stack %p\n", stack); + while (stack) { + phpdbg_debug_param(stack, "\t -> "); + stack = stack->next; + } yy_delete_buffer(state, scanner); yylex_destroy(scanner); - } else fprintf(stderr, "could not parse input (%s) !!\n", buffer); + } } else fprintf(stderr, "could not get input !!\n"); + + free(stack); } while (1); return 0; } + %} %code requires { @@ -88,7 +115,7 @@ typedef void* yyscan_t; %define api.pure %lex-param { yyscan_t scanner } -%parse-param { phpdbg_param_t **expression } +%parse-param { phpdbg_param_t **stack } %parse-param { yyscan_t scanner } %token C_TRUTHY "truthy (true, on, yes or enabled)" @@ -108,25 +135,32 @@ typedef void* yyscan_t; %% input - : handler {} + : handler ; parameters - : parameters parameter { phpdbg_debug_param(&$2, "got another parameter"); } - | parameter { phpdbg_debug_param(&$1, "got first parameter"); } + : parameter { phpdbg_stack_push(*stack, &$1); } + | parameters parameter { phpdbg_stack_push(*stack, &$2); } ; params - : /* empty */ { /* do nothing */ } - | parameters { $$ = $1; } + : /* empty */ + | parameters + ; + +normal + : T_ID { phpdbg_stack_push(*stack, &$1); } + | normal T_ID { phpdbg_stack_push(*stack, &$2); } + ; + +special + : C_EVAL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } + | C_SHELL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } ; command - : T_ID { fprintf(stderr, "got cmd: %s\n", $1.str); } - | T_ID T_ID { fprintf(stderr, "got sub: %s -> %s\n", $1.str, $2.str); } - /* exceptional cases below */ - | C_EVAL T_INPUT { fprintf(stderr, "got eval: %s\n", $2.str); } - | C_SHELL T_INPUT { fprintf(stderr, "got shell: %s\n", $2.str); } + : normal + | special ; parameter @@ -141,6 +175,6 @@ parameter ; handler - : command params {} + : command params ; %% From a9e0202a5ddb37a4ddcd50490b6e58105c427015 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 21:38:55 +0000 Subject: [PATCH 043/137] remove leaks from stack traverse the other way fix id regex, thanks @bwoebi --- phpdbg_cmd.h | 25 +++++----- phpdbg_lexer.l | 4 +- phpdbg_parser.y | 125 ++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 116 insertions(+), 38 deletions(-) diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 6eb4e73e904..698c1b55449 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -40,7 +40,8 @@ typedef enum { STR_PARAM, NUMERIC_PARAM, NUMERIC_FUNCTION_PARAM, - NUMERIC_METHOD_PARAM + NUMERIC_METHOD_PARAM, + STACK_PARAM } phpdbg_param_type; typedef struct _phpdbg_input_t phpdbg_input_t; @@ -69,19 +70,21 @@ struct _phpdbg_param { char *str; size_t len; phpdbg_param_t *next; + phpdbg_param_t *top; }; #define phpdbg_init_param(v, t) do{ \ - v->type = t; \ - v->addr = 0; \ - v->num = 0; \ - v->file.name = NULL; \ - v->file.line = 0; \ - v->method.class = NULL; \ - v->method.name = NULL; \ - v->str = NULL; \ - v->len = 0; \ - v->next = NULL; \ + (v)->type = (t); \ + (v)->addr = 0; \ + (v)->num = 0; \ + (v)->file.name = NULL; \ + (v)->file.line = 0; \ + (v)->method.class = NULL; \ + (v)->method.name = NULL; \ + (v)->str = NULL; \ + (v)->len = 0; \ + (v)->next = NULL; \ + (v)->top = NULL; \ } while(0) typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 3b6c9cae27e..a078f4c40ff 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -33,9 +33,9 @@ C_EVAL "eval" C_SHELL "shell" DIGITS [0-9]+ -ID [a-zA-Z][a-zA-Z0-9_]+ +ID [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* METHOD {ID}::{ID} -FILE [^ :0-9]{1,}:[0-9]+ +FILE [^ :]+:[0-9]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" WS [ \r\n\t]+ diff --git a/phpdbg_parser.y b/phpdbg_parser.y index dfc13a48e15..e0819fe6e15 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -14,6 +14,13 @@ #define YYSTYPE phpdbg_param_t +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { + fprintf(stderr, "Parse Error: %s\n", msg); +} + void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { if (param && param->type) { switch (param->type) { @@ -40,8 +47,38 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { } } -#include "phpdbg_parser.h" -#include "phpdbg_lexer.h" +static void phpdbg_stack_free(phpdbg_param_t *stack) { + if (stack && stack->next) { + phpdbg_param_t *remove = stack->next; + + while (remove) { + phpdbg_param_t *next = NULL; + + if (remove->next) + next = remove->next; + + switch (remove->type) { + case STR_PARAM: + if (remove->str) { + free(remove->str); + } + break; + + case FILE_PARAM: + if (remove->file.name) { + free(remove->file.name); + } + break; + } + + free(remove); + + if (next) + remove = next; + else break; + } + } +} static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); @@ -51,19 +88,51 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { *(next) = *(param); - if (stack->addr) { - next->next = - stack->next; + if (stack->top == NULL) { + stack->top = next; + stack->next = next; } else { - stack->addr = (ulong) next; + stack->top->next = next; + next->top = stack->top; + stack->top = next; } - stack->next = next; stack->len++; } -int yyerror(phpdbg_param_t **param, yyscan_t scanner, const char *msg) { - fprintf(stderr, "Parse Error: %s\n", msg); +static int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { + phpdbg_param_t *command = NULL, + *params = NULL; + + if (stack->type != STACK_PARAM) { + asprintf( + why, "the passed argument was not a stack !!"); + return FAILURE; + } + + if (!stack->len) { + asprintf( + why, "the stack contains nothing !!"); + return FAILURE; + } + + command = params = (phpdbg_param_t*) stack->next; + + if (command->type != STR_PARAM) { + asprintf( + why, "the first parameter is expected to be a string !!"); + return FAILURE; + } + + /* do resolve command(s) */ + + /* do prepare params for function */ + while (params) { + phpdbg_debug_param(params, "-> ..."); + params = params->next; + } + + return SUCCESS; } int main(int argc, char **argv) { @@ -72,9 +141,9 @@ int main(int argc, char **argv) { YY_BUFFER_STATE state; char buffer[8096]; size_t buflen = 0L; - phpdbg_param_t *stack = malloc(sizeof(phpdbg_param_t)); + phpdbg_param_t stack; - phpdbg_init_param(stack, EMPTY_PARAM); + phpdbg_init_param(&stack, STACK_PARAM); if (fgets(&buffer[0], 8096, stdin) != NULL) { if (yylex_init(&scanner)) { @@ -85,17 +154,23 @@ int main(int argc, char **argv) { state = yy_scan_string(buffer, scanner); if (yyparse(&stack, scanner) <= 0) { - fprintf(stderr, "got stack %p\n", stack); - while (stack) { - phpdbg_debug_param(stack, "\t -> "); - stack = stack->next; + char *why = NULL; + + if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { + fprintf(stderr, + "Execution Error: %s\n", + why ? why : "for no particular reason"); + } + + if (why) { + free(why); } - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); } + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); } else fprintf(stderr, "could not get input !!\n"); - free(stack); + phpdbg_stack_free(&stack); } while (1); return 0; @@ -115,7 +190,7 @@ typedef void* yyscan_t; %define api.pure %lex-param { yyscan_t scanner } -%parse-param { phpdbg_param_t **stack } +%parse-param { phpdbg_param_t *stack } %parse-param { yyscan_t scanner } %token C_TRUTHY "truthy (true, on, yes or enabled)" @@ -139,8 +214,8 @@ input ; parameters - : parameter { phpdbg_stack_push(*stack, &$1); } - | parameters parameter { phpdbg_stack_push(*stack, &$2); } + : parameter { phpdbg_stack_push(stack, &$1); } + | parameters parameter { phpdbg_stack_push(stack, &$2); } ; params @@ -149,13 +224,13 @@ params ; normal - : T_ID { phpdbg_stack_push(*stack, &$1); } - | normal T_ID { phpdbg_stack_push(*stack, &$2); } + : T_ID { phpdbg_stack_push(stack, &$1); } + | normal T_ID { phpdbg_stack_push(stack, &$2); } ; special - : C_EVAL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } - | C_SHELL T_INPUT { phpdbg_stack_push(*stack, &$1); phpdbg_stack_push(*stack, &$2); } + : C_EVAL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } + | C_SHELL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } ; command From d392de0ff71b52cc205860169a3afed4f385d249 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 21:52:25 +0000 Subject: [PATCH 044/137] fix lexer for namespaced methods --- phpdbg_lexer.l | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index a078f4c40ff..66532c4bd74 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -34,7 +34,8 @@ C_SHELL "shell" DIGITS [0-9]+ ID [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* -METHOD {ID}::{ID} +NSID [\\\\]?{ID} +METHOD {NSID}+::{ID} FILE [^ :]+:[0-9]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" From c3bf5dc904c6b6d80d4a0bda68a305014b8107fc Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 22:47:20 +0000 Subject: [PATCH 045/137] modify command to parse arguments with lexer for testingz --- config.m4 | 4 +- phpdbg_lexer.l => dev/phpdbg_lexer.l | 6 +- phpdbg_parser.y => dev/phpdbg_parser.y | 48 +- phpdbg_cmd.c | 55 +- phpdbg_cmd.h | 4 + phpdbg_lexer.c | 2160 ++++++++++++++++++++++++ phpdbg_lexer.h | 346 ++++ phpdbg_parser.c | 1863 ++++++++++++++++++++ phpdbg_parser.h | 81 + 9 files changed, 4517 insertions(+), 50 deletions(-) rename phpdbg_lexer.l => dev/phpdbg_lexer.l (94%) rename phpdbg_parser.y => dev/phpdbg_parser.y (80%) create mode 100644 phpdbg_lexer.c create mode 100644 phpdbg_lexer.h create mode 100644 phpdbg_parser.c create mode 100644 phpdbg_parser.h diff --git a/config.m4 b/config.m4 index c48a5db60fc..51425d6f9c8 100644 --- a/config.m4 +++ b/config.m4 @@ -18,7 +18,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_parser.c phpdbg_lexer.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c phpdbg_set.c phpdbg_frame.c" if test "$PHP_READLINE" != "no"; then PHPDBG_EXTRA_LIBS="-lreadline" @@ -33,7 +33,7 @@ if test "$PHP_PHPDBG" != "no"; then BUILD_BINARY="sapi/phpdbg/phpdbg" BUILD_SHARED="sapi/phpdbg/libphpdbg.la" - + BUILD_PHPDBG="\$(LIBTOOL) --mode=link \ \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \ \$(PHP_GLOBAL_OBJS) \ diff --git a/phpdbg_lexer.l b/dev/phpdbg_lexer.l similarity index 94% rename from phpdbg_lexer.l rename to dev/phpdbg_lexer.l index 66532c4bd74..ff90f1255dc 100644 --- a/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -15,7 +15,7 @@ %s RAW -%option outfile="phpdbg_lexer.c" header-file="phpdbg_lexer.h" +%option outfile="sapi/phpdbg/phpdbg_lexer.c" header-file="sapi/phpdbg/phpdbg_lexer.h" %option warn nodefault %option reentrant noyywrap never-interactive nounistd @@ -66,9 +66,9 @@ INPUT [^\n]+ phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; - return C_SHELL; + return C_SHELL; } - {DIGITS} { + {DIGITS} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; diff --git a/phpdbg_parser.y b/dev/phpdbg_parser.y similarity index 80% rename from phpdbg_parser.y rename to dev/phpdbg_parser.y index e0819fe6e15..c5de549c7df 100644 --- a/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -47,7 +47,7 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { } } -static void phpdbg_stack_free(phpdbg_param_t *stack) { +void phpdbg_stack_free(phpdbg_param_t *stack) { if (stack && stack->next) { phpdbg_param_t *remove = stack->next; @@ -100,7 +100,7 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { stack->len++; } -static int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { +int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { phpdbg_param_t *command = NULL, *params = NULL; @@ -135,46 +135,6 @@ static int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return SUCCESS; } -int main(int argc, char **argv) { - do { - yyscan_t scanner; - YY_BUFFER_STATE state; - char buffer[8096]; - size_t buflen = 0L; - phpdbg_param_t stack; - - phpdbg_init_param(&stack, STACK_PARAM); - - if (fgets(&buffer[0], 8096, stdin) != NULL) { - if (yylex_init(&scanner)) { - fprintf(stderr, "could not initialize scanner\n"); - return 1; - } - - state = yy_scan_string(buffer, scanner); - - if (yyparse(&stack, scanner) <= 0) { - char *why = NULL; - - if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { - fprintf(stderr, - "Execution Error: %s\n", - why ? why : "for no particular reason"); - } - - if (why) { - free(why); - } - } - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); - } else fprintf(stderr, "could not get input !!\n"); - - phpdbg_stack_free(&stack); - } while (1); - - return 0; -} %} @@ -185,8 +145,8 @@ typedef void* yyscan_t; #endif } %expect 1 -%output "phpdbg_parser.c" -%defines "phpdbg_parser.h" +%output "sapi/phpdbg/phpdbg_parser.c" +%defines "sapi/phpdbg/phpdbg_parser.h" %define api.pure %lex-param { yyscan_t scanner } diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 1d78c533216..2fcf31305af 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -22,12 +22,20 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); +void phpdbg_stack_free(phpdbg_param_t *stack); +int yyparse(phpdbg_param_t *stack, yyscan_t scanner); ZEND_EXTERN_MODULE_GLOBALS(phpdbg); PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { switch (param->type) { + case STACK_PARAM: + return "stack"; case EMPTY_PARAM: return "empty"; case ADDR_PARAM: @@ -208,6 +216,10 @@ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **point PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* dest TSRMLS_DC) /* {{{ */ { switch ((dest->type = src->type)) { + case STACK_PARAM: + /* nope */ + break; + case STR_PARAM: dest->str = estrndup(src->str, src->len); dest->len = src->len; @@ -254,6 +266,10 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / zend_ulong hash = param->type; switch (param->type) { + case STACK_PARAM: + /* nope */ + break; + case STR_PARAM: hash += zend_inline_hash_func(param->str, param->len); break; @@ -301,7 +317,11 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa if (l && r) { if (l->type == r->type) { switch (l->type) { - + case STACK_PARAM: + /* nope, or yep */ + return 1; + break; + case NUMERIC_FUNCTION_PARAM: if (l->num != r->num) { break; @@ -528,6 +548,39 @@ readline: buffer->argv = phpdbg_read_argv( buffer->string, &buffer->argc TSRMLS_CC); + { + yyscan_t scanner; + YY_BUFFER_STATE state; + phpdbg_param_t stack; + + phpdbg_init_param(&stack, STACK_PARAM); + + if (yylex_init(&scanner)) { + fprintf(stderr, "could not initialize scanner\n"); + return buffer; + } + + state = yy_scan_string(buffer->string, scanner); + + if (yyparse(&stack, scanner) <= 0) { + char *why = NULL; + + if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { + fprintf(stderr, + "Execution Error: %s\n", + why ? why : "for no particular reason"); + } + + if (why) { + free(why); + } + } + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); + + phpdbg_stack_free(&stack); + } + #ifdef PHPDBG_DEBUG if (buffer->argc) { int arg = 0; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 698c1b55449..7cfe35ba9ea 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -87,6 +87,10 @@ struct _phpdbg_param { (v)->top = NULL; \ } while(0) +#ifndef YYSTYPE +#define YYSTYPE phpdbg_param_t +#endif + typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); struct _phpdbg_command_t { diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c new file mode 100644 index 00000000000..f4a7f324bb7 --- /dev/null +++ b/phpdbg_lexer.c @@ -0,0 +1,2160 @@ +#line 2 "sapi/phpdbg/phpdbg_lexer.c" + +#line 4 "sapi/phpdbg/phpdbg_lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void yypop_buffer_state (yyscan_t yyscanner ); + +static void yyensure_buffer_stack (yyscan_t yyscanner ); +static void yy_load_buffer_state (yyscan_t yyscanner ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void yyfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 14 +#define YY_END_OF_BUFFER 15 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[83] = + { 0, + 0, 0, 0, 0, 15, 13, 12, 12, 12, 13, + 5, 5, 13, 10, 13, 10, 10, 10, 10, 10, + 10, 10, 10, 11, 11, 12, 0, 0, 12, 12, + 0, 0, 9, 0, 0, 5, 0, 10, 0, 10, + 0, 0, 10, 10, 10, 10, 2, 10, 1, 10, + 10, 10, 11, 11, 7, 9, 0, 7, 8, 0, + 0, 0, 10, 10, 10, 10, 10, 10, 6, 10, + 10, 3, 10, 10, 6, 10, 10, 4, 10, 10, + 10, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 1, 5, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 1, 1, + 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 1, 11, 1, 1, 10, 1, 12, 13, 9, 14, + + 15, 16, 10, 17, 18, 10, 10, 19, 10, 20, + 21, 10, 10, 22, 23, 24, 25, 26, 10, 27, + 28, 10, 1, 1, 1, 1, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10 + } ; + +static yyconst flex_int32_t yy_meta[29] = + { 0, + 1, 1, 2, 3, 1, 4, 4, 1, 5, 5, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5 + } ; + +static yyconst flex_int16_t yy_base[93] = + { 0, + 0, 0, 27, 30, 264, 245, 33, 36, 43, 44, + 50, 53, 269, 77, 88, 99, 44, 51, 32, 55, + 25, 50, 36, 0, 63, 109, 241, 80, 112, 119, + 120, 87, 236, 127, 132, 135, 138, 216, 149, 207, + 157, 168, 58, 85, 149, 90, 206, 111, 121, 162, + 101, 160, 0, 182, 142, 269, 134, 182, 0, 0, + 193, 0, 154, 179, 163, 184, 172, 188, 0, 192, + 190, 112, 196, 194, 0, 197, 202, 100, 203, 205, + 208, 269, 226, 231, 236, 241, 246, 251, 256, 261, + 69, 263 + + } ; + +static yyconst flex_int16_t yy_def[93] = + { 0, + 82, 1, 83, 83, 82, 84, 84, 84, 82, 85, + 84, 84, 82, 86, 87, 86, 16, 16, 16, 16, + 16, 16, 16, 88, 88, 82, 84, 82, 84, 82, + 85, 89, 84, 89, 85, 84, 84, 16, 82, 16, + 87, 90, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 88, 88, 82, 82, 89, 89, 37, 91, + 90, 61, 16, 16, 16, 16, 16, 16, 92, 16, + 16, 16, 16, 16, 92, 16, 16, 16, 16, 16, + 16, 0, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82 + + } ; + +static yyconst flex_int16_t yy_nxt[298] = + { 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, + 15, 14, 14, 16, 17, 18, 14, 14, 14, 19, + 20, 14, 21, 22, 14, 14, 14, 23, 25, 26, + 25, 25, 26, 25, 29, 29, 30, 29, 29, 30, + 28, 50, 40, 28, 30, 30, 30, 32, 33, 40, + 52, 34, 47, 40, 35, 36, 36, 28, 36, 36, + 28, 40, 46, 44, 54, 30, 54, 40, 40, 45, + 48, 51, 40, 69, 49, 40, 37, 27, 27, 27, + 63, 27, 38, 38, 39, 55, 55, 41, 27, 27, + 27, 56, 27, 27, 27, 28, 64, 57, 27, 27, + + 27, 27, 40, 27, 38, 38, 39, 40, 66, 41, + 30, 30, 30, 29, 29, 30, 43, 40, 40, 28, + 30, 30, 30, 32, 33, 68, 47, 34, 40, 40, + 35, 56, 58, 58, 27, 32, 82, 57, 40, 34, + 36, 36, 28, 59, 59, 28, 59, 55, 55, 59, + 59, 59, 59, 59, 55, 55, 60, 27, 27, 27, + 65, 27, 27, 27, 28, 70, 40, 27, 27, 27, + 27, 40, 27, 61, 61, 39, 67, 40, 41, 40, + 40, 72, 49, 54, 30, 54, 56, 58, 58, 40, + 74, 71, 57, 27, 27, 27, 40, 27, 61, 61, + + 39, 40, 49, 41, 76, 40, 73, 40, 77, 40, + 47, 40, 78, 40, 40, 79, 80, 81, 49, 40, + 40, 47, 40, 40, 40, 40, 24, 24, 24, 24, + 24, 27, 27, 40, 27, 27, 31, 31, 31, 31, + 31, 40, 40, 28, 40, 40, 42, 42, 28, 42, + 42, 53, 28, 53, 53, 53, 32, 32, 32, 32, + 32, 62, 62, 82, 62, 62, 75, 75, 5, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82 + + } ; + +static yyconst flex_int16_t yy_chk[298] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 3, 4, 4, 4, 7, 7, 7, 8, 8, 8, + 7, 21, 21, 8, 9, 9, 9, 10, 10, 19, + 23, 10, 19, 23, 10, 11, 11, 11, 12, 12, + 12, 17, 18, 17, 25, 25, 25, 22, 18, 17, + 20, 22, 20, 91, 20, 43, 11, 14, 14, 14, + 43, 14, 14, 14, 14, 28, 28, 14, 15, 15, + 15, 32, 15, 15, 15, 15, 44, 32, 15, 16, + + 16, 16, 44, 16, 16, 16, 16, 46, 46, 16, + 26, 26, 26, 29, 29, 29, 16, 78, 51, 29, + 30, 30, 30, 31, 31, 51, 48, 31, 48, 72, + 31, 34, 34, 34, 35, 35, 57, 34, 49, 35, + 36, 36, 36, 37, 37, 37, 37, 55, 55, 37, + 37, 37, 37, 37, 39, 39, 39, 41, 41, 41, + 45, 41, 41, 41, 41, 63, 45, 41, 42, 42, + 42, 63, 42, 42, 42, 42, 50, 52, 42, 50, + 65, 65, 52, 54, 54, 54, 58, 58, 58, 67, + 67, 64, 58, 61, 61, 61, 64, 61, 61, 61, + + 61, 66, 68, 61, 70, 68, 66, 71, 71, 70, + 73, 74, 74, 73, 76, 76, 77, 79, 80, 77, + 79, 81, 80, 47, 40, 81, 83, 83, 83, 83, + 83, 84, 84, 38, 84, 84, 85, 85, 85, 85, + 85, 86, 86, 33, 86, 86, 87, 87, 27, 87, + 87, 88, 6, 88, 88, 88, 89, 89, 89, 89, + 89, 90, 90, 5, 90, 90, 92, 92, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82 + + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "sapi/phpdbg/phpdbg_lexer.l" +#line 2 "sapi/phpdbg/phpdbg_lexer.l" + +/* + * phpdbg_lexer.l + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" +#define YYSTYPE phpdbg_param_t + +#include "phpdbg_parser.h" +#include +#include + +#define YY_NO_UNISTD_H 1 +#line 541 "sapi/phpdbg/phpdbg_lexer.c" + +#define INITIAL 0 +#define RAW 1 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (yyscan_t yyscanner ); + +int yyget_debug (yyscan_t yyscanner ); + +void yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *yyget_in (yyscan_t yyscanner ); + +void yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *yyget_out (yyscan_t yyscanner ); + +void yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +int yyget_leng (yyscan_t yyscanner ); + +char *yyget_text (yyscan_t yyscanner ); + +int yyget_lineno (yyscan_t yyscanner ); + +void yyset_lineno (int line_number ,yyscan_t yyscanner ); + +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + +YYSTYPE * yyget_lval (yyscan_t yyscanner ); + +void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (yyscan_t yyscanner ); +#else +extern int yywrap (yyscan_t yyscanner ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + unsigned n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ,yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + +#line 44 "sapi/phpdbg/phpdbg_lexer.l" + +#line 781 "sapi/phpdbg/phpdbg_lexer.c" + + yylval = yylval_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 83 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 82 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 47 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 1; + return C_TRUTHY; + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 52 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 0; + return C_FALSY; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 57 "sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return C_EVAL; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 64 "sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return C_SHELL; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 71 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = atoi(yytext); + return T_DIGITS; + } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 76 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, METHOD_PARAM); + yylval->method.class = "class"; + yylval->method.name = "func"; + return T_METHOD; + } + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 82 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, FILE_PARAM); + yylval->file.name = strndup(yytext, yyleng); + yylval->file.line = 0; + return T_FILE; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 88 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, ADDR_PARAM); + yylval->addr = strtoul(yytext, NULL, 10); + return T_OPLINE; + } + YY_BREAK +case 9: +/* rule 9 can match eol */ +YY_RULE_SETUP +#line 93 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_LITERAL; + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 99 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_ID; + } + YY_BREAK + +case 11: +YY_RULE_SETUP +#line 106 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + BEGIN(INITIAL); + return T_INPUT; +} + YY_BREAK +case 12: +/* rule 12 can match eol */ +YY_RULE_SETUP +#line 113 "sapi/phpdbg/phpdbg_lexer.l" +{ /* ignore whitespace */ } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 114 "sapi/phpdbg/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_UNEXPECTED; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 118 "sapi/phpdbg/phpdbg_lexer.l" +YY_FATAL_ERROR( "flex scanner jammed" ); + YY_BREAK +#line 993 "sapi/phpdbg/phpdbg_lexer.c" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(RAW): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( yywrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 83 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 83 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 82); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) +{ + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_cp = yyg->yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yyg->yy_hold_char; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yyg->yy_n_chars + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + yyg->yytext_ptr = yy_bp; + yyg->yy_hold_char = *yy_cp; + yyg->yy_c_buf_p = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + yy_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void yy_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * @param yyscanner The scanner object. + */ + void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ,yyscanner ); + + yyfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(yyscanner); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void yypop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (yyscan_t yyscanner) +{ + int num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int yyget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int yyget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *yyget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int yyget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *yyget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void yyset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "yyset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void yyset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int yyget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void yyset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * yyget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +/* User-visible API */ + +/* yylex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int yylex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* yylex_init_extra has the same functionality as yylex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to yyalloc in + * the yyextra field. + */ + +int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + yyset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + yyset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + yyfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + yyfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + yyfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 118 "sapi/phpdbg/phpdbg_lexer.l" + + + diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h new file mode 100644 index 00000000000..b016d96689b --- /dev/null +++ b/phpdbg_lexer.h @@ -0,0 +1,346 @@ +#ifndef yyHEADER_H +#define yyHEADER_H 1 +#define yyIN_HEADER 1 + +#line 6 "sapi/phpdbg/phpdbg_lexer.h" + +#line 8 "sapi/phpdbg/phpdbg_lexer.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart (FILE *input_file ,yyscan_t yyscanner ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void yypop_buffer_state (yyscan_t yyscanner ); + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *yyalloc (yy_size_t ,yyscan_t yyscanner ); +void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void yyfree (void * ,yyscan_t yyscanner ); + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +#define yytext_ptr yytext_r + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 +#define RAW 1 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +int yylex_init (yyscan_t* scanner); + +int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (yyscan_t yyscanner ); + +int yyget_debug (yyscan_t yyscanner ); + +void yyset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *yyget_in (yyscan_t yyscanner ); + +void yyset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *yyget_out (yyscan_t yyscanner ); + +void yyset_out (FILE * out_str ,yyscan_t yyscanner ); + +int yyget_leng (yyscan_t yyscanner ); + +char *yyget_text (yyscan_t yyscanner ); + +int yyget_lineno (yyscan_t yyscanner ); + +void yyset_lineno (int line_number ,yyscan_t yyscanner ); + +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + +YYSTYPE * yyget_lval (yyscan_t yyscanner ); + +void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (yyscan_t yyscanner ); +#else +extern int yywrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ,yyscan_t yyscanner); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#line 118 "sapi/phpdbg/phpdbg_lexer.l" + + +#line 345 "sapi/phpdbg/phpdbg_lexer.h" +#undef yyIN_HEADER +#endif /* yyHEADER_H */ diff --git a/phpdbg_parser.c b/phpdbg_parser.c new file mode 100644 index 00000000000..b6a7fe20c16 --- /dev/null +++ b/phpdbg_parser.c @@ -0,0 +1,1863 @@ +/* A Bison parser, made by GNU Bison 2.5. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.5" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Copy the first part of user declarations. */ + +/* Line 268 of yacc.c */ +#line 2 "sapi/phpdbg/phpdbg_parser.y" + + +/* + * phpdbg_parser.y + * + * flex phpdbg_lexer.l + * bison phpdbg_parser.y + * gcc -g -o parser phpdbg_lexer.c phpdbg_parser.c -I/usr/src/php-src/main -I/usr/src/php-src/Zend -I/usr/src/php-src/TSRM -I/usr/src/php-src + */ + +#include "phpdbg.h" +#include "phpdbg_cmd.h" + +#define YYSTYPE phpdbg_param_t + +#include "phpdbg_parser.h" +#include "phpdbg_lexer.h" + +int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { + fprintf(stderr, "Parse Error: %s\n", msg); +} + +void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { + if (param && param->type) { + switch (param->type) { + case STR_PARAM: + fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); + break; + + case ADDR_PARAM: + fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); + break; + + case FILE_PARAM: + fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); + break; + + case METHOD_PARAM: + fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_PARAM: + fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); + break; + } + } +} + +void phpdbg_stack_free(phpdbg_param_t *stack) { + if (stack && stack->next) { + phpdbg_param_t *remove = stack->next; + + while (remove) { + phpdbg_param_t *next = NULL; + + if (remove->next) + next = remove->next; + + switch (remove->type) { + case STR_PARAM: + if (remove->str) { + free(remove->str); + } + break; + + case FILE_PARAM: + if (remove->file.name) { + free(remove->file.name); + } + break; + } + + free(remove); + + if (next) + remove = next; + else break; + } + } +} + +static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { + phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); + + if (!next) + return; + + *(next) = *(param); + + if (stack->top == NULL) { + stack->top = next; + stack->next = next; + } else { + stack->top->next = next; + next->top = stack->top; + stack->top = next; + } + + stack->len++; +} + +int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { + phpdbg_param_t *command = NULL, + *params = NULL; + + if (stack->type != STACK_PARAM) { + asprintf( + why, "the passed argument was not a stack !!"); + return FAILURE; + } + + if (!stack->len) { + asprintf( + why, "the stack contains nothing !!"); + return FAILURE; + } + + command = params = (phpdbg_param_t*) stack->next; + + if (command->type != STR_PARAM) { + asprintf( + why, "the first parameter is expected to be a string !!"); + return FAILURE; + } + + /* do resolve command(s) */ + + /* do prepare params for function */ + while (params) { + phpdbg_debug_param(params, "-> ..."); + params = params->next; + } + + return SUCCESS; +} + + + + +/* Line 268 of yacc.c */ +#line 211 "sapi/phpdbg/phpdbg_parser.c" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +/* "%code requires" blocks. */ + +/* Line 288 of yacc.c */ +#line 141 "sapi/phpdbg/phpdbg_parser.y" + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + + +/* Line 288 of yacc.c */ +#line 244 "sapi/phpdbg/phpdbg_parser.c" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + C_TRUTHY = 258, + C_FALSY = 259, + C_STRING = 260, + C_EVAL = 261, + C_SHELL = 262, + T_DIGITS = 263, + T_LITERAL = 264, + T_METHOD = 265, + T_OPLINE = 266, + T_FILE = 267, + T_ID = 268, + T_INPUT = 269, + T_UNEXPECTED = 270 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + +/* Line 343 of yacc.c */ +#line 282 "sapi/phpdbg/phpdbg_parser.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 11 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 18 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 16 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 9 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 21 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 25 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 270 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 7, 10, 11, 13, 15, 18, + 21, 24, 26, 28, 30, 32, 34, 36, 38, 40, + 42, 44 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 17, 0, -1, 24, -1, 23, -1, 18, 23, -1, + -1, 18, -1, 13, -1, 20, 13, -1, 6, 14, + -1, 7, 14, -1, 20, -1, 21, -1, 8, -1, + 12, -1, 10, -1, 11, -1, 13, -1, 9, -1, + 3, -1, 4, -1, 22, 19, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 173, 173, 177, 178, 181, 183, 187, 188, 192, + 193, 197, 198, 202, 203, 204, 205, 206, 207, 208, + 209, 213 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "\"truthy (true, on, yes or enabled)\"", + "\"falsy (false, off, no or disabled)\"", + "\"string (some input, perhaps)\"", "\"eval\"", "\"shell\"", + "\"digits (numbers)\"", "\"literal (T_LITERAL)\"", + "\"method (T_METHOD)\"", "\"opline (T_OPLINE)\"", "\"file (T_FILE)\"", + "\"identifier (T_ID)\"", "\"input (input string or data)\"", + "\"unexpected input (input string or data)\"", "$accept", "input", + "parameters", "params", "normal", "special", "command", "parameter", + "handler", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 16, 17, 18, 18, 19, 19, 20, 20, 21, + 21, 22, 22, 23, 23, 23, 23, 23, 23, 23, + 23, 24 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2 +}; + +/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 7, 0, 11, 12, 5, 2, 9, + 10, 1, 8, 19, 20, 13, 18, 15, 16, 14, + 17, 6, 21, 3, 4 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 4, 21, 22, 5, 6, 7, 23, 8 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -13 +static const yytype_int8 yypact[] = +{ + 5, -12, -11, -13, 4, 0, -13, -3, -13, -13, + -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, + -13, -3, -13, -13, -13 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -13, -13, -13, -13, -13, -13, -13, -7, -13 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 13, 14, 9, 10, 11, 15, 16, 17, 18, 19, + 20, 1, 2, 12, 24, 0, 0, 0, 3 +}; + +#define yypact_value_is_default(yystate) \ + ((yystate) == (-13)) + +#define yytable_value_is_error(yytable_value) \ + YYID (0) + +static const yytype_int8 yycheck[] = +{ + 3, 4, 14, 14, 0, 8, 9, 10, 11, 12, + 13, 6, 7, 13, 21, -1, -1, -1, 13 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 6, 7, 13, 17, 20, 21, 22, 24, 14, + 14, 0, 13, 3, 4, 8, 9, 10, 11, 12, + 13, 18, 19, 23, 23 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (stack, scanner, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* This macro is provided for backward compatibility. */ + +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, scanner) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, stack, scanner); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + phpdbg_param_t *stack; + yyscan_t scanner; +#endif +{ + if (!yyvaluep) + return; + YYUSE (stack); + YYUSE (scanner); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, stack, scanner) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + phpdbg_param_t *stack; + yyscan_t scanner; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, phpdbg_param_t *stack, yyscan_t scanner) +#else +static void +yy_reduce_print (yyvsp, yyrule, stack, scanner) + YYSTYPE *yyvsp; + int yyrule; + phpdbg_param_t *stack; + yyscan_t scanner; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , stack, scanner); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, stack, scanner); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = 0; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + for details. YYERROR is fine as it does not invoke this + function. + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, stack, scanner) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + phpdbg_param_t *stack; + yyscan_t scanner; +#endif +{ + YYUSE (yyvaluep); + YYUSE (stack); + YYUSE (scanner); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (phpdbg_param_t *stack, yyscan_t scanner); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (phpdbg_param_t *stack, yyscan_t scanner) +#else +int +yyparse (stack, scanner) + phpdbg_param_t *stack; + yyscan_t scanner; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 3: + +/* Line 1806 of yacc.c */ +#line 177 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } + break; + + case 4: + +/* Line 1806 of yacc.c */ +#line 178 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } + break; + + case 7: + +/* Line 1806 of yacc.c */ +#line 187 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } + break; + + case 8: + +/* Line 1806 of yacc.c */ +#line 188 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } + break; + + case 9: + +/* Line 1806 of yacc.c */ +#line 192 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } + break; + + case 10: + +/* Line 1806 of yacc.c */ +#line 193 "sapi/phpdbg/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } + break; + + case 13: + +/* Line 1806 of yacc.c */ +#line 202 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 14: + +/* Line 1806 of yacc.c */ +#line 203 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 15: + +/* Line 1806 of yacc.c */ +#line 204 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 16: + +/* Line 1806 of yacc.c */ +#line 205 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 17: + +/* Line 1806 of yacc.c */ +#line 206 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 18: + +/* Line 1806 of yacc.c */ +#line 207 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 19: + +/* Line 1806 of yacc.c */ +#line 208 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 20: + +/* Line 1806 of yacc.c */ +#line 209 "sapi/phpdbg/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + + +/* Line 1806 of yacc.c */ +#line 1631 "sapi/phpdbg/phpdbg_parser.c" + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (stack, scanner, YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (stack, scanner, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, stack, scanner); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, stack, scanner); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (stack, scanner, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, stack, scanner); + } + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, stack, scanner); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + +/* Line 2067 of yacc.c */ +#line 215 "sapi/phpdbg/phpdbg_parser.y" + + diff --git a/phpdbg_parser.h b/phpdbg_parser.h new file mode 100644 index 00000000000..0fc9ed8cc04 --- /dev/null +++ b/phpdbg_parser.h @@ -0,0 +1,81 @@ +/* A Bison parser, made by GNU Bison 2.5. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* "%code requires" blocks. */ + +/* Line 2068 of yacc.c */ +#line 141 "sapi/phpdbg/phpdbg_parser.y" + +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + + + +/* Line 2068 of yacc.c */ +#line 47 "sapi/phpdbg/phpdbg_parser.h" + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + C_TRUTHY = 258, + C_FALSY = 259, + C_STRING = 260, + C_EVAL = 261, + C_SHELL = 262, + T_DIGITS = 263, + T_LITERAL = 264, + T_METHOD = 265, + T_OPLINE = 266, + T_FILE = 267, + T_ID = 268, + T_INPUT = 269, + T_UNEXPECTED = 270 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + + + From ff95046b764ff43d2733734c2e5a401a232c5d60 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 22:54:43 +0000 Subject: [PATCH 046/137] ... --- dev/phpdbg_lexer.l | 2 +- phpdbg_lexer.c | 230 ++++++++++++++++++++++----------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 34 +++---- phpdbg_parser.h | 2 +- 5 files changed, 135 insertions(+), 135 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index ff90f1255dc..9be1f533b00 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -33,7 +33,7 @@ C_EVAL "eval" C_SHELL "shell" DIGITS [0-9]+ -ID [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* +ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-]* NSID [\\\\]?{ID} METHOD {NSID}+::{ID} FILE [^ :]+:[0-9]+ diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index f4a7f324bb7..0804af5619d 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -361,11 +361,11 @@ struct yy_trans_info static yyconst flex_int16_t yy_accept[83] = { 0, 0, 0, 0, 0, 15, 13, 12, 12, 12, 13, - 5, 5, 13, 10, 13, 10, 10, 10, 10, 10, + 10, 5, 5, 13, 13, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 12, 0, 0, 12, 12, - 0, 0, 9, 0, 0, 5, 0, 10, 0, 10, + 0, 0, 9, 0, 0, 10, 10, 0, 0, 5, 0, 0, 10, 10, 10, 10, 2, 10, 1, 10, - 10, 10, 11, 11, 7, 9, 0, 7, 8, 0, + 10, 10, 11, 11, 7, 9, 0, 7, 0, 8, 0, 0, 10, 10, 10, 10, 10, 10, 6, 10, 10, 3, 10, 10, 6, 10, 10, 4, 10, 10, 10, 0 @@ -377,62 +377,62 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 5, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 8, 1, 1, - 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 1, 11, 1, 1, 10, 1, 12, 13, 9, 14, + 1, 1, 1, 1, 6, 1, 1, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, + 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 1, 11, 1, 1, 6, 1, 12, 13, 10, 14, - 15, 16, 10, 17, 18, 10, 10, 19, 10, 20, - 21, 10, 10, 22, 23, 24, 25, 26, 10, 27, - 28, 10, 1, 1, 1, 1, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 15, 16, 6, 17, 18, 6, 6, 19, 6, 20, + 21, 6, 6, 22, 23, 24, 25, 26, 6, 27, + 28, 6, 1, 1, 1, 1, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10 + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6 } ; static yyconst flex_int32_t yy_meta[29] = { 0, - 1, 1, 2, 3, 1, 4, 4, 1, 5, 5, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5 + 1, 1, 2, 3, 1, 4, 5, 5, 1, 4, + 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4 } ; static yyconst flex_int16_t yy_base[93] = { 0, - 0, 0, 27, 30, 264, 245, 33, 36, 43, 44, - 50, 53, 269, 77, 88, 99, 44, 51, 32, 55, - 25, 50, 36, 0, 63, 109, 241, 80, 112, 119, - 120, 87, 236, 127, 132, 135, 138, 216, 149, 207, - 157, 168, 58, 85, 149, 90, 206, 111, 121, 162, - 101, 160, 0, 182, 142, 269, 134, 182, 0, 0, - 193, 0, 154, 179, 163, 184, 172, 188, 0, 192, - 190, 112, 196, 194, 0, 197, 202, 100, 203, 205, - 208, 269, 226, 231, 236, 241, 246, 251, 256, 261, - 69, 263 + 0, 0, 27, 30, 247, 228, 33, 36, 44, 45, + 56, 44, 61, 272, 71, 82, 68, 48, 23, 79, + 84, 59, 88, 0, 105, 108, 219, 97, 111, 114, + 117, 87, 208, 122, 128, 179, 144, 116, 137, 127, + 142, 158, 150, 129, 152, 153, 135, 158, 125, 160, + 37, 159, 0, 177, 176, 272, 116, 180, 0, 0, + 191, 0, 177, 188, 185, 187, 189, 194, 0, 198, + 195, 78, 200, 201, 0, 203, 208, 57, 209, 172, + 211, 272, 229, 234, 239, 244, 249, 254, 259, 264, + 39, 266 } ; static yyconst flex_int16_t yy_def[93] = { 0, 82, 1, 83, 83, 82, 84, 84, 84, 82, 85, - 84, 84, 82, 86, 87, 86, 16, 16, 16, 16, + 86, 84, 84, 82, 87, 86, 16, 16, 16, 16, 16, 16, 16, 88, 88, 82, 84, 82, 84, 82, - 85, 89, 84, 89, 85, 84, 84, 16, 82, 16, - 87, 90, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 88, 88, 82, 82, 89, 89, 37, 91, + 85, 89, 84, 89, 85, 16, 16, 82, 87, 84, + 84, 90, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 88, 88, 82, 82, 89, 89, 91, 41, 90, 61, 16, 16, 16, 16, 16, 16, 92, 16, 16, 16, 16, 16, 92, 16, 16, 16, 16, 16, 16, 0, 82, 82, 82, 82, 82, 82, 82, 82, @@ -440,77 +440,77 @@ static yyconst flex_int16_t yy_def[93] = } ; -static yyconst flex_int16_t yy_nxt[298] = +static yyconst flex_int16_t yy_nxt[301] = { 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, - 15, 14, 14, 16, 17, 18, 14, 14, 14, 19, - 20, 14, 21, 22, 14, 14, 14, 23, 25, 26, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 11, + 15, 11, 11, 16, 17, 18, 11, 11, 11, 19, + 20, 11, 21, 22, 11, 11, 11, 23, 25, 26, 25, 25, 26, 25, 29, 29, 30, 29, 29, 30, - 28, 50, 40, 28, 30, 30, 30, 32, 33, 40, - 52, 34, 47, 40, 35, 36, 36, 28, 36, 36, - 28, 40, 46, 44, 54, 30, 54, 40, 40, 45, - 48, 51, 40, 69, 49, 40, 37, 27, 27, 27, - 63, 27, 38, 38, 39, 55, 55, 41, 27, 27, - 27, 56, 27, 27, 27, 28, 64, 57, 27, 27, + 36, 28, 69, 47, 28, 30, 30, 30, 32, 33, + 40, 40, 28, 34, 36, 35, 27, 27, 27, 46, + 27, 68, 37, 37, 38, 36, 39, 40, 40, 28, + 41, 27, 27, 27, 36, 27, 36, 27, 27, 28, + 51, 27, 27, 27, 27, 36, 27, 44, 37, 37, + 38, 56, 39, 45, 48, 36, 36, 57, 49, 43, - 27, 27, 40, 27, 38, 38, 39, 40, 66, 41, - 30, 30, 30, 29, 29, 30, 43, 40, 40, 28, - 30, 30, 30, 32, 33, 68, 47, 34, 40, 40, - 35, 56, 58, 58, 27, 32, 82, 57, 40, 34, - 36, 36, 28, 59, 59, 28, 59, 55, 55, 59, - 59, 59, 59, 59, 55, 55, 60, 27, 27, 27, - 65, 27, 27, 27, 28, 70, 40, 27, 27, 27, - 27, 40, 27, 61, 61, 39, 67, 40, 41, 40, - 40, 72, 49, 54, 30, 54, 56, 58, 58, 40, - 74, 71, 57, 27, 27, 27, 40, 27, 61, 61, + 50, 36, 52, 55, 55, 36, 54, 30, 54, 30, + 30, 30, 29, 29, 30, 30, 30, 30, 82, 28, + 32, 33, 55, 55, 59, 34, 56, 35, 58, 58, + 27, 32, 57, 40, 40, 28, 34, 27, 27, 27, + 64, 27, 36, 27, 27, 28, 36, 27, 60, 60, + 28, 60, 36, 60, 60, 60, 60, 60, 27, 27, + 27, 36, 27, 65, 62, 62, 38, 36, 39, 36, + 36, 66, 63, 47, 67, 36, 36, 36, 54, 30, + 54, 49, 55, 55, 56, 49, 58, 58, 70, 36, + 57, 27, 27, 27, 36, 27, 36, 62, 62, 38, - 39, 40, 49, 41, 76, 40, 73, 40, 77, 40, - 47, 40, 78, 40, 40, 79, 80, 81, 49, 40, - 40, 47, 40, 40, 40, 40, 24, 24, 24, 24, - 24, 27, 27, 40, 27, 27, 31, 31, 31, 31, - 31, 40, 40, 28, 40, 40, 42, 42, 28, 42, - 42, 53, 28, 53, 53, 53, 32, 32, 32, 32, - 32, 62, 62, 82, 62, 62, 75, 75, 5, 82, + 71, 39, 36, 72, 36, 36, 36, 74, 49, 73, + 76, 36, 36, 77, 47, 36, 28, 36, 36, 78, + 36, 79, 80, 81, 47, 36, 36, 28, 36, 24, + 24, 24, 24, 24, 27, 27, 28, 27, 27, 31, + 31, 31, 31, 31, 36, 36, 82, 36, 36, 42, + 42, 82, 42, 42, 53, 82, 53, 53, 53, 32, + 32, 32, 32, 32, 61, 61, 82, 61, 61, 75, + 75, 5, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82 + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82 } ; -static yyconst flex_int16_t yy_chk[298] = +static yyconst flex_int16_t yy_chk[301] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, 7, 7, 7, 8, 8, 8, - 7, 21, 21, 8, 9, 9, 9, 10, 10, 19, - 23, 10, 19, 23, 10, 11, 11, 11, 12, 12, - 12, 17, 18, 17, 25, 25, 25, 22, 18, 17, - 20, 22, 20, 91, 20, 43, 11, 14, 14, 14, - 43, 14, 14, 14, 14, 28, 28, 14, 15, 15, - 15, 32, 15, 15, 15, 15, 44, 32, 15, 16, + 19, 7, 91, 19, 8, 9, 9, 9, 10, 10, + 12, 12, 12, 10, 51, 10, 11, 11, 11, 18, + 11, 51, 11, 11, 11, 18, 11, 13, 13, 13, + 12, 15, 15, 15, 78, 15, 22, 15, 15, 15, + 22, 15, 16, 16, 16, 17, 16, 17, 16, 16, + 16, 32, 16, 17, 20, 72, 20, 32, 20, 16, - 16, 16, 44, 16, 16, 16, 16, 46, 46, 16, - 26, 26, 26, 29, 29, 29, 16, 78, 51, 29, - 30, 30, 30, 31, 31, 51, 48, 31, 48, 72, - 31, 34, 34, 34, 35, 35, 57, 34, 49, 35, - 36, 36, 36, 37, 37, 37, 37, 55, 55, 37, - 37, 37, 37, 37, 39, 39, 39, 41, 41, 41, - 45, 41, 41, 41, 41, 63, 45, 41, 42, 42, - 42, 63, 42, 42, 42, 42, 50, 52, 42, 50, - 65, 65, 52, 54, 54, 54, 58, 58, 58, 67, - 67, 64, 58, 61, 61, 61, 64, 61, 61, 61, + 21, 21, 23, 28, 28, 23, 25, 25, 25, 26, + 26, 26, 29, 29, 29, 30, 30, 30, 57, 29, + 31, 31, 38, 38, 38, 31, 34, 31, 34, 34, + 35, 35, 34, 40, 40, 40, 35, 39, 39, 39, + 44, 39, 49, 39, 39, 39, 44, 39, 41, 41, + 41, 41, 47, 41, 41, 41, 41, 41, 42, 42, + 42, 37, 42, 45, 42, 42, 42, 43, 42, 45, + 46, 46, 43, 48, 50, 48, 52, 50, 54, 54, + 54, 52, 55, 55, 58, 80, 58, 58, 63, 80, + 58, 61, 61, 61, 63, 61, 36, 61, 61, 61, - 61, 66, 68, 61, 70, 68, 66, 71, 71, 70, - 73, 74, 74, 73, 76, 76, 77, 79, 80, 77, - 79, 81, 80, 47, 40, 81, 83, 83, 83, 83, - 83, 84, 84, 38, 84, 84, 85, 85, 85, 85, - 85, 86, 86, 33, 86, 86, 87, 87, 27, 87, - 87, 88, 6, 88, 88, 88, 89, 89, 89, 89, - 89, 90, 90, 5, 90, 90, 92, 92, 82, 82, + 64, 61, 65, 65, 66, 64, 67, 67, 68, 66, + 70, 68, 71, 71, 73, 70, 33, 73, 74, 74, + 76, 76, 77, 79, 81, 77, 79, 27, 81, 83, + 83, 83, 83, 83, 84, 84, 6, 84, 84, 85, + 85, 85, 85, 85, 86, 86, 5, 86, 86, 87, + 87, 0, 87, 87, 88, 0, 88, 88, 88, 89, + 89, 89, 89, 89, 90, 90, 0, 90, 90, 92, + 92, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82 + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82 } ; @@ -521,8 +521,8 @@ static yyconst flex_int16_t yy_chk[298] = #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET -#line 1 "sapi/phpdbg/phpdbg_lexer.l" -#line 2 "sapi/phpdbg/phpdbg_lexer.l" +#line 1 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 2 "sapi/phpdbg/dev/phpdbg_lexer.l" /* * phpdbg_lexer.l @@ -775,7 +775,7 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 44 "sapi/phpdbg/phpdbg_lexer.l" +#line 44 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 781 "sapi/phpdbg/phpdbg_lexer.c" @@ -860,7 +860,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 47 "sapi/phpdbg/phpdbg_lexer.l" +#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -869,7 +869,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 52 "sapi/phpdbg/phpdbg_lexer.l" +#line 52 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; @@ -878,7 +878,7 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 57 "sapi/phpdbg/phpdbg_lexer.l" +#line 57 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, STR_PARAM); @@ -889,7 +889,7 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 64 "sapi/phpdbg/phpdbg_lexer.l" +#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, STR_PARAM); @@ -900,7 +900,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 71 "sapi/phpdbg/phpdbg_lexer.l" +#line 71 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -909,7 +909,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 76 "sapi/phpdbg/phpdbg_lexer.l" +#line 76 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, METHOD_PARAM); yylval->method.class = "class"; @@ -920,7 +920,7 @@ YY_RULE_SETUP case 7: /* rule 7 can match eol */ YY_RULE_SETUP -#line 82 "sapi/phpdbg/phpdbg_lexer.l" +#line 82 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, FILE_PARAM); yylval->file.name = strndup(yytext, yyleng); @@ -930,7 +930,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 88 "sapi/phpdbg/phpdbg_lexer.l" +#line 88 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); @@ -940,7 +940,7 @@ YY_RULE_SETUP case 9: /* rule 9 can match eol */ YY_RULE_SETUP -#line 93 "sapi/phpdbg/phpdbg_lexer.l" +#line 93 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -950,7 +950,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 99 "sapi/phpdbg/phpdbg_lexer.l" +#line 99 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -961,7 +961,7 @@ YY_RULE_SETUP case 11: YY_RULE_SETUP -#line 106 "sapi/phpdbg/phpdbg_lexer.l" +#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -973,12 +973,12 @@ YY_RULE_SETUP case 12: /* rule 12 can match eol */ YY_RULE_SETUP -#line 113 "sapi/phpdbg/phpdbg_lexer.l" +#line 113 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK case 13: YY_RULE_SETUP -#line 114 "sapi/phpdbg/phpdbg_lexer.l" +#line 114 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, EMPTY_PARAM); return T_UNEXPECTED; @@ -986,7 +986,7 @@ YY_RULE_SETUP YY_BREAK case 14: YY_RULE_SETUP -#line 118 "sapi/phpdbg/phpdbg_lexer.l" +#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK #line 993 "sapi/phpdbg/phpdbg_lexer.c" @@ -2154,7 +2154,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 118 "sapi/phpdbg/phpdbg_lexer.l" +#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index b016d96689b..c6d9f1b8bc0 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 118 "sapi/phpdbg/phpdbg_lexer.l" +#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index b6a7fe20c16..be6049a8295 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -66,7 +66,7 @@ /* Copy the first part of user declarations. */ /* Line 268 of yacc.c */ -#line 2 "sapi/phpdbg/phpdbg_parser.y" +#line 2 "sapi/phpdbg/dev/phpdbg_parser.y" /* @@ -230,7 +230,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 141 "sapi/phpdbg/phpdbg_parser.y" +#line 141 "sapi/phpdbg/dev/phpdbg_parser.y" #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T @@ -1529,98 +1529,98 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 177 "sapi/phpdbg/phpdbg_parser.y" +#line 177 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 178 "sapi/phpdbg/phpdbg_parser.y" +#line 178 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 187 "sapi/phpdbg/phpdbg_parser.y" +#line 187 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 188 "sapi/phpdbg/phpdbg_parser.y" +#line 188 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 192 "sapi/phpdbg/phpdbg_parser.y" +#line 192 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 10: /* Line 1806 of yacc.c */ -#line 193 "sapi/phpdbg/phpdbg_parser.y" +#line 193 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 202 "sapi/phpdbg/phpdbg_parser.y" +#line 202 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 203 "sapi/phpdbg/phpdbg_parser.y" +#line 203 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 204 "sapi/phpdbg/phpdbg_parser.y" +#line 204 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 205 "sapi/phpdbg/phpdbg_parser.y" +#line 205 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 206 "sapi/phpdbg/phpdbg_parser.y" +#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 207 "sapi/phpdbg/phpdbg_parser.y" +#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 208 "sapi/phpdbg/phpdbg_parser.y" +#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 209 "sapi/phpdbg/phpdbg_parser.y" +#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; @@ -1858,6 +1858,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 215 "sapi/phpdbg/phpdbg_parser.y" +#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 0fc9ed8cc04..3b4d8bbbe4a 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 141 "sapi/phpdbg/phpdbg_parser.y" +#line 141 "sapi/phpdbg/dev/phpdbg_parser.y" #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T From 4af3e39147f0a54c9d78dcabbd4dd8438ce3d07b Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 23:12:24 +0000 Subject: [PATCH 047/137] improve error reporting --- dev/phpdbg_parser.y | 6 +++++- phpdbg_cmd.c | 8 +++---- phpdbg_parser.c | 52 ++++++++++++++++++++++++--------------------- phpdbg_parser.h | 5 +++-- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index c5de549c7df..23d3a581785 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -11,14 +11,17 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" +#include "phpdbg_utils.h" #define YYSTYPE phpdbg_param_t #include "phpdbg_parser.h" #include "phpdbg_lexer.h" +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { - fprintf(stderr, "Parse Error: %s\n", msg); + phpdbg_error("Parse Error: %s", msg); } void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { @@ -139,6 +142,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { %} %code requires { +#include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 2fcf31305af..526d1183a57 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -556,7 +556,7 @@ readline: phpdbg_init_param(&stack, STACK_PARAM); if (yylex_init(&scanner)) { - fprintf(stderr, "could not initialize scanner\n"); + phpdbg_error("could not initialize scanner"); return buffer; } @@ -566,11 +566,11 @@ readline: char *why = NULL; if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { - fprintf(stderr, - "Execution Error: %s\n", + phpdbg_error( + "Execution Error: %s", why ? why : "for no particular reason"); } - + if (why) { free(why); } diff --git a/phpdbg_parser.c b/phpdbg_parser.c index be6049a8295..3dc7b4802ec 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -79,14 +79,17 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" +#include "phpdbg_utils.h" #define YYSTYPE phpdbg_param_t #include "phpdbg_parser.h" #include "phpdbg_lexer.h" +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { - fprintf(stderr, "Parse Error: %s\n", msg); + phpdbg_error("Parse Error: %s", msg); } void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { @@ -207,7 +210,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* Line 268 of yacc.c */ -#line 211 "sapi/phpdbg/phpdbg_parser.c" +#line 214 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -230,8 +233,9 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 141 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" +#include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; @@ -240,7 +244,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 244 "sapi/phpdbg/phpdbg_parser.c" +#line 248 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -278,7 +282,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 282 "sapi/phpdbg/phpdbg_parser.c" +#line 286 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -571,9 +575,9 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 173, 173, 177, 178, 181, 183, 187, 188, 192, - 193, 197, 198, 202, 203, 204, 205, 206, 207, 208, - 209, 213 + 0, 177, 177, 181, 182, 185, 187, 191, 192, 196, + 197, 201, 202, 206, 207, 208, 209, 210, 211, 212, + 213, 217 }; #endif @@ -1529,105 +1533,105 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 177 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 181 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 178 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 182 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 187 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 191 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 188 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 192 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 192 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 196 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 10: /* Line 1806 of yacc.c */ -#line 193 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 197 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 202 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 203 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 204 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 205 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 210 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 211 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 213 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; /* Line 1806 of yacc.c */ -#line 1631 "sapi/phpdbg/phpdbg_parser.c" +#line 1635 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1858,6 +1862,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 219 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 3b4d8bbbe4a..57d8e7fe29e 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,8 +33,9 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 141 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" +#include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; @@ -43,7 +44,7 @@ typedef void* yyscan_t; /* Line 2068 of yacc.c */ -#line 47 "sapi/phpdbg/phpdbg_parser.h" +#line 48 "sapi/phpdbg/phpdbg_parser.h" /* Tokens. */ #ifndef YYTOKENTYPE From 3cabee71ab57020336aa92378e406199dc551397 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 16 Feb 2014 23:17:16 +0000 Subject: [PATCH 048/137] ... --- dev/phpdbg_parser.y | 19 +++++++------- phpdbg_parser.c | 60 ++++++++++++++++++++++----------------------- phpdbg_parser.h | 2 +- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 23d3a581785..713c0efccf8 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -3,10 +3,9 @@ /* * phpdbg_parser.y - * - * flex phpdbg_lexer.l - * bison phpdbg_parser.y - * gcc -g -o parser phpdbg_lexer.c phpdbg_parser.c -I/usr/src/php-src/main -I/usr/src/php-src/Zend -I/usr/src/php-src/TSRM -I/usr/src/php-src + * (from php-src root) + * flex sapi/phpdbg/dev/phpdbg_lexer.l + * bison sapi/phpdbg/dev/phpdbg_parser.y */ #include "phpdbg.h" @@ -164,13 +163,13 @@ typedef void* yyscan_t; %token C_SHELL "shell" %token T_DIGITS "digits (numbers)" -%token T_LITERAL "literal (T_LITERAL)" -%token T_METHOD "method (T_METHOD)" -%token T_OPLINE "opline (T_OPLINE)" -%token T_FILE "file (T_FILE)" -%token T_ID "identifier (T_ID)" +%token T_LITERAL "literal (string)" +%token T_METHOD "method" +%token T_OPLINE "opline" +%token T_FILE "file" +%token T_ID "identifier (command or function name)" %token T_INPUT "input (input string or data)" -%token T_UNEXPECTED "unexpected input (input string or data)" +%token T_UNEXPECTED "input" %% input diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 3dc7b4802ec..2c8cbfce515 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -71,10 +71,9 @@ /* * phpdbg_parser.y - * - * flex phpdbg_lexer.l - * bison phpdbg_parser.y - * gcc -g -o parser phpdbg_lexer.c phpdbg_parser.c -I/usr/src/php-src/main -I/usr/src/php-src/Zend -I/usr/src/php-src/TSRM -I/usr/src/php-src + * (from php-src root) + * flex sapi/phpdbg/dev/phpdbg_lexer.l + * bison sapi/phpdbg/dev/phpdbg_parser.y */ #include "phpdbg.h" @@ -210,7 +209,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* Line 268 of yacc.c */ -#line 214 "sapi/phpdbg/phpdbg_parser.c" +#line 213 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -233,7 +232,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 143 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -244,7 +243,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 248 "sapi/phpdbg/phpdbg_parser.c" +#line 247 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -282,7 +281,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 286 "sapi/phpdbg/phpdbg_parser.c" +#line 285 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -575,9 +574,9 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 177, 177, 181, 182, 185, 187, 191, 192, 196, - 197, 201, 202, 206, 207, 208, 209, 210, 211, 212, - 213, 217 + 0, 176, 176, 180, 181, 184, 186, 190, 191, 195, + 196, 200, 201, 205, 206, 207, 208, 209, 210, 211, + 212, 216 }; #endif @@ -589,10 +588,9 @@ static const char *const yytname[] = "$end", "error", "$undefined", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", "\"string (some input, perhaps)\"", "\"eval\"", "\"shell\"", - "\"digits (numbers)\"", "\"literal (T_LITERAL)\"", - "\"method (T_METHOD)\"", "\"opline (T_OPLINE)\"", "\"file (T_FILE)\"", - "\"identifier (T_ID)\"", "\"input (input string or data)\"", - "\"unexpected input (input string or data)\"", "$accept", "input", + "\"digits (numbers)\"", "\"literal (string)\"", "\"method\"", + "\"opline\"", "\"file\"", "\"identifier (command or function name)\"", + "\"input (input string or data)\"", "\"input\"", "$accept", "input", "parameters", "params", "normal", "special", "command", "parameter", "handler", 0 }; @@ -1533,105 +1531,105 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 181 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 180 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 182 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 181 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 191 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 190 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 192 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 191 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 196 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 195 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 10: /* Line 1806 of yacc.c */ -#line 197 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 196 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 205 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 210 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 211 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 210 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 211 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 213 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; /* Line 1806 of yacc.c */ -#line 1635 "sapi/phpdbg/phpdbg_parser.c" +#line 1633 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1862,6 +1860,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 219 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 218 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 57d8e7fe29e..08a4e9ce969 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 143 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T From 1641d2afbe559bb3d95a6afe62b006ee90b17f1a Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 17 Feb 2014 08:53:47 +0000 Subject: [PATCH 049/137] case insensitivity where we can additional param types --- dev/phpdbg_lexer.l | 52 ++++--- dev/phpdbg_parser.y | 44 ++++-- phpdbg_cmd.h | 6 +- phpdbg_lexer.c | 371 +++++++++++++++++++++++++------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 193 ++++++++++++++--------- phpdbg_parser.h | 19 +-- 7 files changed, 401 insertions(+), 286 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 9be1f533b00..76c28c45dd6 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -21,16 +21,17 @@ %option reentrant noyywrap never-interactive nounistd %option bison-bridge -C_TRUE "true" -C_YES "yes" -C_ON "on" -C_ENABLED "enabled" -C_FALSE "false" -C_NO "no" -C_OFF "off" -C_DISABLED "disabled" -C_EVAL "eval" -C_SHELL "shell" +C_TRUE ?i:"true" +C_YES ?i:"yes" +C_ON ?i:"on" +C_ENABLED ?i:"enabled" +C_FALSE ?i:"false" +C_NO ?i:"no" +C_OFF ?i:"off" +C_DISABLED ?i:"disabled" +C_EVAL ?i:"eval" +C_SHELL ?i:"shell" +C_IF ?i:"if" DIGITS [0-9]+ ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-]* @@ -44,6 +45,21 @@ INPUT [^\n]+ %% { + {C_EVAL} { + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_EVAL; + } + {C_SHELL} { + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_SHELL; + } + {C_IF} { + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_IF; + } {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -54,20 +70,6 @@ INPUT [^\n]+ yylval->num = 0; return C_FALSY; } - {C_EVAL} { - BEGIN(RAW); - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return C_EVAL; - } - {C_SHELL} { - BEGIN(RAW); - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return C_SHELL; - } {DIGITS} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -96,7 +98,7 @@ INPUT [^\n]+ yylval->len = yyleng; return T_LITERAL; } - {ID} { + {NSID} { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 713c0efccf8..185283eb8e1 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -45,6 +45,10 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; + + case COND_PARAM: + fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); + break; } } } @@ -119,16 +123,28 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { } command = params = (phpdbg_param_t*) stack->next; - - if (command->type != STR_PARAM) { - asprintf( - why, "the first parameter is expected to be a string !!"); - return FAILURE; + + switch (command->type) { + case EVAL_PARAM: + phpdbg_notice("eval (%s)", command->str); + break; + + case SHELL_PARAM: + phpdbg_notice("shell (%s)", command->str); + break; + + case STR_PARAM: { + /* do resolve command(s) */ + } break; + + default: + asprintf( + why, "the first parameter makes no sense !!"); + return FAILURE; } - /* do resolve command(s) */ - /* do prepare params for function */ + while (params) { phpdbg_debug_param(params, "-> ..."); params = params->next; @@ -161,6 +177,7 @@ typedef void* yyscan_t; %token C_STRING "string (some input, perhaps)" %token C_EVAL "eval" %token C_SHELL "shell" +%token C_IF "if (condition)" %token T_DIGITS "digits (numbers)" %token T_LITERAL "literal (string)" @@ -187,18 +204,18 @@ params ; normal - : T_ID { phpdbg_stack_push(stack, &$1); } - | normal T_ID { phpdbg_stack_push(stack, &$2); } + : T_ID { $$ = $1; } + | normal T_ID { $$ = $2; } ; special - : C_EVAL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } - | C_SHELL T_INPUT { phpdbg_stack_push(stack, &$1); phpdbg_stack_push(stack, &$2); } + : C_EVAL T_INPUT { $$ = $2; $$.type = EVAL_PARAM; } + | C_SHELL T_INPUT { $$ = $2; $$.type = SHELL_PARAM;; } ; command - : normal - | special + : normal { phpdbg_stack_push(stack, &$1); } + | special { phpdbg_stack_push(stack, &$1); } ; parameter @@ -210,6 +227,7 @@ parameter | T_LITERAL { $$ = $1; } | C_TRUTHY { $$ = $1; } | C_FALSY { $$ = $1; } + | C_IF T_INPUT { $$ = $2; $$.type = COND_PARAM; } ; handler diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 7cfe35ba9ea..cf503812a72 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -41,7 +41,11 @@ typedef enum { NUMERIC_PARAM, NUMERIC_FUNCTION_PARAM, NUMERIC_METHOD_PARAM, - STACK_PARAM + STACK_PARAM, + EVAL_PARAM, + SHELL_PARAM, + COND_PARAM, + ORIG_PARAM } phpdbg_param_type; typedef struct _phpdbg_input_t phpdbg_input_t; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 0804af5619d..cc8535fe5c6 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 14 -#define YY_END_OF_BUFFER 15 +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,17 +358,19 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[83] = +static yyconst flex_int16_t yy_accept[92] = { 0, - 0, 0, 0, 0, 15, 13, 12, 12, 12, 13, - 10, 5, 5, 13, 13, 10, 10, 10, 10, 10, - 10, 10, 10, 11, 11, 12, 0, 0, 12, 12, - 0, 0, 9, 0, 0, 10, 10, 0, 0, 5, - 0, 0, 10, 10, 10, 10, 2, 10, 1, 10, - 10, 10, 11, 11, 7, 9, 0, 7, 0, 8, - 0, 0, 10, 10, 10, 10, 10, 10, 6, 10, - 10, 3, 10, 10, 6, 10, 10, 4, 10, 10, - 10, 0 + 0, 0, 0, 0, 16, 14, 13, 13, 13, 14, + 11, 6, 6, 14, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 14, 12, 12, 13, 0, 0, 13, + 13, 0, 0, 10, 0, 0, 11, 11, 0, 0, + 6, 0, 11, 11, 11, 11, 3, 5, 11, 4, + 11, 11, 11, 11, 12, 12, 8, 10, 0, 8, + 0, 0, 9, 11, 11, 11, 11, 5, 11, 11, + 4, 7, 0, 0, 11, 11, 1, 11, 11, 4, + 7, 11, 11, 5, 2, 11, 11, 11, 4, 5, + 0 + } ; static yyconst flex_int32_t yy_ec[256] = @@ -379,14 +381,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 4, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, - 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 1, 11, 1, 1, 6, 1, 12, 13, 10, 14, + 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, + 6, 16, 17, 6, 6, 18, 6, 19, 20, 6, + 6, 21, 22, 23, 24, 25, 6, 6, 26, 6, + 1, 27, 1, 1, 6, 1, 28, 29, 12, 30, - 15, 16, 6, 17, 18, 6, 6, 19, 6, 20, - 21, 6, 6, 22, 23, 24, 25, 26, 6, 27, - 28, 6, 1, 1, 1, 1, 6, 6, 6, 6, + 31, 32, 6, 33, 34, 6, 6, 35, 6, 36, + 37, 6, 6, 38, 39, 40, 41, 42, 6, 43, + 44, 6, 1, 1, 1, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -403,115 +405,157 @@ static yyconst flex_int32_t yy_ec[256] = 6, 6, 6, 6, 6 } ; -static yyconst flex_int32_t yy_meta[29] = +static yyconst flex_int32_t yy_meta[45] = { 0, 1, 1, 2, 3, 1, 4, 5, 5, 1, 4, - 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4 + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4 } ; -static yyconst flex_int16_t yy_base[93] = +static yyconst flex_int16_t yy_base[103] = { 0, - 0, 0, 27, 30, 247, 228, 33, 36, 44, 45, - 56, 44, 61, 272, 71, 82, 68, 48, 23, 79, - 84, 59, 88, 0, 105, 108, 219, 97, 111, 114, - 117, 87, 208, 122, 128, 179, 144, 116, 137, 127, - 142, 158, 150, 129, 152, 153, 135, 158, 125, 160, - 37, 159, 0, 177, 176, 272, 116, 180, 0, 0, - 191, 0, 177, 188, 185, 187, 189, 194, 0, 198, - 195, 78, 200, 201, 0, 203, 208, 57, 209, 172, - 211, 272, 229, 234, 239, 244, 249, 254, 259, 264, - 39, 266 + 0, 0, 43, 46, 161, 150, 49, 52, 60, 61, + 88, 60, 64, 433, 115, 58, 70, 42, 65, 93, + 97, 116, 121, 155, 0, 103, 137, 125, 71, 142, + 163, 164, 116, 77, 167, 144, 67, 92, 169, 194, + 172, 215, 166, 176, 203, 172, 94, 102, 200, 153, + 202, 218, 231, 175, 0, 236, 177, 433, 78, 249, + 0, 276, 0, 241, 238, 256, 265, 246, 271, 278, + 276, 0, 312, 339, 316, 290, 277, 318, 319, 284, + 0, 338, 343, 309, 317, 344, 346, 351, 345, 348, + 433, 385, 390, 395, 400, 405, 410, 415, 420, 56, + 425, 427 } ; -static yyconst flex_int16_t yy_def[93] = +static yyconst flex_int16_t yy_def[103] = { 0, - 82, 1, 83, 83, 82, 84, 84, 84, 82, 85, - 86, 84, 84, 82, 87, 86, 16, 16, 16, 16, - 16, 16, 16, 88, 88, 82, 84, 82, 84, 82, - 85, 89, 84, 89, 85, 16, 16, 82, 87, 84, - 84, 90, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 88, 88, 82, 82, 89, 89, 91, 41, - 90, 61, 16, 16, 16, 16, 16, 16, 92, 16, - 16, 16, 16, 16, 92, 16, 16, 16, 16, 16, - 16, 0, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82 + 91, 1, 92, 92, 91, 93, 93, 93, 91, 94, + 95, 93, 93, 91, 95, 15, 15, 15, 15, 15, + 15, 15, 15, 96, 97, 97, 91, 93, 91, 93, + 91, 94, 98, 93, 98, 94, 15, 15, 91, 99, + 93, 93, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 97, 97, 91, 91, 98, 98, + 100, 101, 42, 15, 15, 15, 15, 15, 15, 15, + 15, 102, 101, 101, 15, 15, 15, 15, 15, 15, + 102, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91 } ; -static yyconst flex_int16_t yy_nxt[301] = +static yyconst flex_int16_t yy_nxt[478] = { 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 11, - 15, 11, 11, 16, 17, 18, 11, 11, 11, 19, - 20, 11, 21, 22, 11, 11, 11, 23, 25, 26, - 25, 25, 26, 25, 29, 29, 30, 29, 29, 30, - 36, 28, 69, 47, 28, 30, 30, 30, 32, 33, - 40, 40, 28, 34, 36, 35, 27, 27, 27, 46, - 27, 68, 37, 37, 38, 36, 39, 40, 40, 28, - 41, 27, 27, 27, 36, 27, 36, 27, 27, 28, - 51, 27, 27, 27, 27, 36, 27, 44, 37, 37, - 38, 56, 39, 45, 48, 36, 36, 57, 49, 43, + 11, 11, 15, 16, 17, 11, 18, 11, 19, 20, + 11, 21, 22, 11, 11, 23, 24, 11, 11, 15, + 16, 17, 11, 18, 11, 19, 20, 11, 21, 22, + 11, 11, 11, 23, 26, 27, 26, 26, 27, 26, + 30, 30, 31, 30, 30, 31, 47, 29, 37, 72, + 29, 31, 31, 31, 33, 34, 41, 41, 29, 35, + 41, 41, 29, 47, 37, 37, 44, 57, 57, 46, + 91, 37, 45, 37, 48, 29, 37, 36, 28, 28, + 28, 37, 28, 44, 38, 38, 39, 46, 37, 45, - 50, 36, 52, 55, 55, 36, 54, 30, 54, 30, - 30, 30, 29, 29, 30, 30, 30, 30, 82, 28, - 32, 33, 55, 55, 59, 34, 56, 35, 58, 58, - 27, 32, 57, 40, 40, 28, 34, 27, 27, 27, - 64, 27, 36, 27, 27, 28, 36, 27, 60, 60, - 28, 60, 36, 60, 60, 60, 60, 60, 27, 27, - 27, 36, 27, 65, 62, 62, 38, 36, 39, 36, - 36, 66, 63, 47, 67, 36, 36, 36, 54, 30, - 54, 49, 55, 55, 56, 49, 58, 58, 70, 36, - 57, 27, 27, 27, 36, 27, 36, 62, 62, 38, + 37, 48, 42, 37, 56, 31, 56, 49, 37, 37, + 37, 50, 51, 37, 40, 28, 28, 28, 37, 28, + 58, 38, 38, 39, 49, 37, 37, 37, 50, 51, + 37, 43, 37, 29, 53, 37, 52, 37, 31, 31, + 31, 40, 59, 30, 30, 31, 28, 33, 43, 37, + 29, 53, 35, 52, 37, 28, 28, 28, 29, 28, + 91, 28, 28, 29, 31, 31, 31, 33, 34, 37, + 91, 58, 35, 60, 60, 57, 57, 61, 41, 41, + 29, 28, 37, 57, 57, 65, 37, 64, 37, 67, + 36, 37, 37, 59, 28, 28, 28, 91, 28, 37, - 71, 39, 36, 72, 36, 36, 36, 74, 49, 73, - 76, 36, 36, 77, 47, 36, 28, 36, 36, 78, - 36, 79, 80, 81, 47, 36, 36, 28, 36, 24, - 24, 24, 24, 24, 27, 27, 28, 27, 27, 31, - 31, 31, 31, 31, 36, 36, 82, 36, 36, 42, - 42, 82, 42, 42, 53, 82, 53, 53, 53, 32, - 32, 32, 32, 32, 61, 61, 82, 61, 61, 75, - 75, 5, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82 + 28, 28, 29, 65, 64, 37, 67, 91, 37, 37, + 91, 91, 66, 91, 68, 69, 37, 91, 37, 37, + 28, 63, 63, 29, 63, 63, 63, 63, 63, 63, + 66, 68, 69, 37, 37, 37, 37, 56, 31, 56, + 91, 70, 63, 63, 63, 63, 63, 37, 76, 91, + 75, 37, 71, 58, 37, 60, 60, 37, 70, 91, + 91, 91, 37, 91, 37, 91, 76, 91, 75, 71, + 91, 37, 37, 77, 37, 59, 28, 28, 28, 37, + 28, 37, 74, 74, 39, 91, 78, 37, 79, 37, + 77, 80, 37, 37, 37, 91, 91, 91, 37, 91, + 37, 91, 40, 78, 37, 79, 37, 83, 80, 37, + 37, 37, 28, 28, 28, 91, 28, 37, 74, 74, + 39, 91, 91, 37, 83, 37, 82, 91, 91, 91, + 91, 84, 37, 37, 37, 37, 85, 91, 40, 28, + 28, 28, 37, 28, 82, 74, 74, 39, 84, 37, + 37, 37, 37, 85, 37, 86, 87, 88, 89, 37, + 37, 37, 37, 90, 37, 40, 91, 37, 91, 91, + 91, 37, 86, 87, 88, 89, 37, 37, 37, 37, + 90, 37, 91, 91, 37, 25, 25, 25, 25, 25, + 28, 28, 91, 28, 28, 32, 32, 32, 32, 32, + + 37, 37, 91, 37, 37, 54, 54, 91, 54, 54, + 55, 91, 55, 55, 55, 33, 33, 33, 33, 33, + 62, 62, 91, 62, 62, 73, 73, 91, 73, 73, + 81, 81, 5, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91 } ; -static yyconst flex_int16_t yy_chk[301] = +static yyconst flex_int16_t yy_chk[478] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, - 3, 4, 4, 4, 7, 7, 7, 8, 8, 8, - 19, 7, 91, 19, 8, 9, 9, 9, 10, 10, - 12, 12, 12, 10, 51, 10, 11, 11, 11, 18, - 11, 51, 11, 11, 11, 18, 11, 13, 13, 13, - 12, 15, 15, 15, 78, 15, 22, 15, 15, 15, - 22, 15, 16, 16, 16, 17, 16, 17, 16, 16, - 16, 32, 16, 17, 20, 72, 20, 32, 20, 16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, + 7, 7, 7, 8, 8, 8, 18, 7, 18, 100, + 8, 9, 9, 9, 10, 10, 12, 12, 12, 10, + 13, 13, 13, 18, 16, 18, 16, 29, 29, 17, + 59, 19, 16, 37, 19, 34, 17, 10, 11, 11, + 11, 16, 11, 16, 11, 11, 11, 17, 19, 16, - 21, 21, 23, 28, 28, 23, 25, 25, 25, 26, - 26, 26, 29, 29, 29, 30, 30, 30, 57, 29, - 31, 31, 38, 38, 38, 31, 34, 31, 34, 34, - 35, 35, 34, 40, 40, 40, 35, 39, 39, 39, - 44, 39, 49, 39, 39, 39, 44, 39, 41, 41, - 41, 41, 47, 41, 41, 41, 41, 41, 42, 42, - 42, 37, 42, 45, 42, 42, 42, 43, 42, 45, - 46, 46, 43, 48, 50, 48, 52, 50, 54, 54, - 54, 52, 55, 55, 58, 80, 58, 58, 63, 80, - 58, 61, 61, 61, 63, 61, 36, 61, 61, 61, + 37, 19, 12, 17, 26, 26, 26, 20, 38, 20, + 47, 20, 21, 21, 11, 15, 15, 15, 48, 15, + 33, 15, 15, 15, 20, 38, 20, 47, 20, 21, + 21, 15, 22, 28, 23, 48, 22, 23, 27, 27, + 27, 15, 33, 30, 30, 30, 36, 36, 15, 22, + 30, 23, 36, 22, 23, 24, 24, 24, 6, 24, + 5, 24, 24, 24, 31, 31, 31, 32, 32, 50, + 0, 35, 32, 35, 35, 39, 39, 39, 41, 41, + 41, 24, 43, 57, 57, 44, 50, 43, 46, 46, + 32, 54, 44, 35, 40, 40, 40, 0, 40, 43, - 64, 61, 65, 65, 66, 64, 67, 67, 68, 66, - 70, 68, 71, 71, 73, 70, 33, 73, 74, 74, - 76, 76, 77, 79, 81, 77, 79, 27, 81, 83, - 83, 83, 83, 83, 84, 84, 6, 84, 84, 85, - 85, 85, 85, 85, 86, 86, 5, 86, 86, 87, - 87, 0, 87, 87, 88, 0, 88, 88, 88, 89, - 89, 89, 89, 89, 90, 90, 0, 90, 90, 92, - 92, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82 + 40, 40, 40, 44, 43, 46, 46, 0, 54, 44, + 0, 0, 45, 0, 49, 51, 49, 0, 51, 45, + 40, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 45, 49, 51, 49, 52, 51, 45, 56, 56, 56, + 0, 52, 42, 42, 42, 42, 42, 53, 65, 0, + 64, 52, 53, 60, 65, 60, 60, 64, 52, 0, + 0, 0, 68, 0, 53, 0, 65, 0, 64, 53, + 0, 65, 66, 66, 64, 60, 62, 62, 62, 68, + 62, 67, 62, 62, 62, 0, 67, 69, 69, 66, + 66, 70, 71, 77, 70, 0, 0, 0, 67, 0, + 80, 0, 62, 67, 69, 69, 76, 76, 70, 71, + 77, 70, 73, 73, 73, 0, 73, 80, 73, 73, + 73, 0, 0, 76, 76, 84, 75, 0, 0, 0, + 0, 78, 75, 85, 78, 79, 79, 0, 73, 74, + 74, 74, 84, 74, 75, 74, 74, 74, 78, 75, + 85, 78, 79, 79, 82, 82, 83, 86, 87, 83, + 86, 89, 87, 88, 90, 74, 0, 88, 0, 0, + 0, 82, 82, 83, 86, 87, 83, 86, 89, 87, + 88, 90, 0, 0, 88, 92, 92, 92, 92, 92, + 93, 93, 0, 93, 93, 94, 94, 94, 94, 94, + + 95, 95, 0, 95, 95, 96, 96, 0, 96, 96, + 97, 0, 97, 97, 97, 98, 98, 98, 98, 98, + 99, 99, 0, 99, 99, 101, 101, 0, 101, 101, + 102, 102, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91 } ; /* The intent behind this definition is that it'll catch @@ -537,7 +581,7 @@ static yyconst flex_int16_t yy_chk[301] = #include #define YY_NO_UNISTD_H 1 -#line 541 "sapi/phpdbg/phpdbg_lexer.c" +#line 585 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -775,9 +819,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 44 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 781 "sapi/phpdbg/phpdbg_lexer.c" +#line 825 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -832,13 +876,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 83 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 82 ); + while ( yy_current_state != 91 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -860,56 +904,61 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_EVAL; + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 53 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_SHELL; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 58 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return C_IF; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return C_TRUTHY; } YY_BREAK -case 2: +case 5: YY_RULE_SETUP -#line 52 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return C_FALSY; } YY_BREAK -case 3: +case 6: YY_RULE_SETUP -#line 57 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return C_EVAL; - } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return C_SHELL; - } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 71 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 76 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, METHOD_PARAM); yylval->method.class = "class"; @@ -917,10 +966,10 @@ YY_RULE_SETUP return T_METHOD; } YY_BREAK -case 7: -/* rule 7 can match eol */ +case 8: +/* rule 8 can match eol */ YY_RULE_SETUP -#line 82 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, FILE_PARAM); yylval->file.name = strndup(yytext, yyleng); @@ -928,19 +977,19 @@ YY_RULE_SETUP return T_FILE; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP -#line 88 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } YY_BREAK -case 9: -/* rule 9 can match eol */ +case 10: +/* rule 10 can match eol */ YY_RULE_SETUP -#line 93 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 95 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -948,9 +997,9 @@ YY_RULE_SETUP return T_LITERAL; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 99 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 101 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -959,9 +1008,9 @@ YY_RULE_SETUP } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 108 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -970,26 +1019,26 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 12: -/* rule 12 can match eol */ +case 13: +/* rule 13 can match eol */ YY_RULE_SETUP -#line 113 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 114 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 116 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, EMPTY_PARAM); return T_UNEXPECTED; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 993 "sapi/phpdbg/phpdbg_lexer.c" +#line 1042 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1285,7 +1334,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 83 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1314,11 +1363,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 83 ) + if ( yy_current_state >= 92 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 82); + yy_is_jam = (yy_current_state == 91); return yy_is_jam ? 0 : yy_current_state; } @@ -2154,7 +2203,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index c6d9f1b8bc0..b835a6695e1 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 118 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 2c8cbfce515..fee118564d3 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -113,6 +113,10 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; + + case COND_PARAM: + fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); + break; } } } @@ -187,16 +191,28 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { } command = params = (phpdbg_param_t*) stack->next; - - if (command->type != STR_PARAM) { - asprintf( - why, "the first parameter is expected to be a string !!"); - return FAILURE; + + switch (command->type) { + case EVAL_PARAM: + phpdbg_notice("eval (%s)", command->str); + break; + + case SHELL_PARAM: + phpdbg_notice("shell (%s)", command->str); + break; + + case STR_PARAM: { + /* do resolve command(s) */ + } break; + + default: + asprintf( + why, "the first parameter makes no sense !!"); + return FAILURE; } - /* do resolve command(s) */ - /* do prepare params for function */ + while (params) { phpdbg_debug_param(params, "-> ..."); params = params->next; @@ -209,7 +225,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* Line 268 of yacc.c */ -#line 213 "sapi/phpdbg/phpdbg_parser.c" +#line 229 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -232,7 +248,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 143 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 159 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -243,7 +259,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 247 "sapi/phpdbg/phpdbg_parser.c" +#line 263 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -256,14 +272,15 @@ typedef void* yyscan_t; C_STRING = 260, C_EVAL = 261, C_SHELL = 262, - T_DIGITS = 263, - T_LITERAL = 264, - T_METHOD = 265, - T_OPLINE = 266, - T_FILE = 267, - T_ID = 268, - T_INPUT = 269, - T_UNEXPECTED = 270 + C_IF = 263, + T_DIGITS = 264, + T_LITERAL = 265, + T_METHOD = 266, + T_OPLINE = 267, + T_FILE = 268, + T_ID = 269, + T_INPUT = 270, + T_UNEXPECTED = 271 }; #endif @@ -281,7 +298,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 285 "sapi/phpdbg/phpdbg_parser.c" +#line 302 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -500,20 +517,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 18 +#define YYLAST 20 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 16 +#define YYNTOKENS 17 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 9 /* YYNRULES -- Number of rules. */ -#define YYNRULES 21 +#define YYNRULES 22 /* YYNRULES -- Number of states. */ -#define YYNSTATES 25 +#define YYNSTATES 27 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 270 +#define YYMAXUTOK 271 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -548,7 +565,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15 + 15, 16 }; #if YYDEBUG @@ -558,25 +575,25 @@ static const yytype_uint8 yyprhs[] = { 0, 0, 3, 5, 7, 10, 11, 13, 15, 18, 21, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44 + 42, 44, 47 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 17, 0, -1, 24, -1, 23, -1, 18, 23, -1, - -1, 18, -1, 13, -1, 20, 13, -1, 6, 14, - -1, 7, 14, -1, 20, -1, 21, -1, 8, -1, - 12, -1, 10, -1, 11, -1, 13, -1, 9, -1, - 3, -1, 4, -1, 22, 19, -1 + 18, 0, -1, 25, -1, 24, -1, 19, 24, -1, + -1, 19, -1, 14, -1, 21, 14, -1, 6, 15, + -1, 7, 15, -1, 21, -1, 22, -1, 9, -1, + 13, -1, 11, -1, 12, -1, 14, -1, 10, -1, + 3, -1, 4, -1, 8, 15, -1, 23, 20, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 176, 176, 180, 181, 184, 186, 190, 191, 195, - 196, 200, 201, 205, 206, 207, 208, 209, 210, 211, - 212, 216 + 0, 193, 193, 197, 198, 201, 203, 207, 208, 212, + 213, 217, 218, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 234 }; #endif @@ -588,8 +605,9 @@ static const char *const yytname[] = "$end", "error", "$undefined", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", "\"string (some input, perhaps)\"", "\"eval\"", "\"shell\"", - "\"digits (numbers)\"", "\"literal (string)\"", "\"method\"", - "\"opline\"", "\"file\"", "\"identifier (command or function name)\"", + "\"if (condition)\"", "\"digits (numbers)\"", "\"literal (string)\"", + "\"method\"", "\"opline\"", "\"file\"", + "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", "parameters", "params", "normal", "special", "command", "parameter", "handler", 0 @@ -602,16 +620,16 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270 + 265, 266, 267, 268, 269, 270, 271 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 16, 17, 18, 18, 19, 19, 20, 20, 21, - 21, 22, 22, 23, 23, 23, 23, 23, 23, 23, - 23, 24 + 0, 17, 18, 19, 19, 20, 20, 21, 21, 22, + 22, 23, 23, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 25 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -619,7 +637,7 @@ static const yytype_uint8 yyr2[] = { 0, 2, 1, 1, 2, 0, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2 + 1, 2, 2 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -628,30 +646,30 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 7, 0, 11, 12, 5, 2, 9, - 10, 1, 8, 19, 20, 13, 18, 15, 16, 14, - 17, 6, 21, 3, 4 + 10, 1, 8, 19, 20, 0, 13, 18, 15, 16, + 14, 17, 6, 22, 3, 21, 4 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 4, 21, 22, 5, 6, 7, 23, 8 + -1, 4, 22, 23, 5, 6, 7, 24, 8 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -13 +#define YYPACT_NINF -14 static const yytype_int8 yypact[] = { - 5, -12, -11, -13, 4, 0, -13, -3, -13, -13, - -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -3, -13, -13, -13 + 6, -13, -12, -14, 4, 0, -14, -3, -14, -14, + -14, -14, -14, -14, -14, 1, -14, -14, -14, -14, + -14, -14, -3, -14, -14, -14, -14 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -13, -13, -13, -13, -13, -13, -13, -7, -13 + -14, -14, -14, -14, -14, -14, -14, -7, -14 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -661,28 +679,30 @@ static const yytype_int8 yypgoto[] = static const yytype_uint8 yytable[] = { 13, 14, 9, 10, 11, 15, 16, 17, 18, 19, - 20, 1, 2, 12, 24, 0, 0, 0, 3 + 20, 21, 1, 2, 12, 26, 25, 0, 0, 0, + 3 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-13)) + ((yystate) == (-14)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 14, 14, 0, 8, 9, 10, 11, 12, - 13, 6, 7, 13, 21, -1, -1, -1, 13 + 3, 4, 15, 15, 0, 8, 9, 10, 11, 12, + 13, 14, 6, 7, 14, 22, 15, -1, -1, -1, + 14 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 6, 7, 13, 17, 20, 21, 22, 24, 14, - 14, 0, 13, 3, 4, 8, 9, 10, 11, 12, - 13, 18, 19, 23, 23 + 0, 6, 7, 14, 18, 21, 22, 23, 25, 15, + 15, 0, 14, 3, 4, 8, 9, 10, 11, 12, + 13, 14, 19, 20, 24, 15, 24 }; #define yyerrok (yyerrstatus = 0) @@ -1531,105 +1551,126 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 180 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 197 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 181 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 198 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 190 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } +#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 8: /* Line 1806 of yacc.c */ -#line 191 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } +#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); } break; case 9: /* Line 1806 of yacc.c */ -#line 195 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } +#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } break; case 10: /* Line 1806 of yacc.c */ -#line 196 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (2)])); phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } +#line 213 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM;; } + break; + + case 11: + +/* Line 1806 of yacc.c */ +#line 217 "sapi/phpdbg/dev/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } + break; + + case 12: + +/* Line 1806 of yacc.c */ +#line 218 "sapi/phpdbg/dev/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 205 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 222 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 206 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 223 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 224 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 225 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 209 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 226 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 210 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 227 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 211 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 228 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 229 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; + case 21: + +/* Line 1806 of yacc.c */ +#line 230 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } + break; + /* Line 1806 of yacc.c */ -#line 1633 "sapi/phpdbg/phpdbg_parser.c" +#line 1674 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1860,6 +1901,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 218 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 236 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 08a4e9ce969..d3ba58aa70e 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 143 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 159 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -57,14 +57,15 @@ typedef void* yyscan_t; C_STRING = 260, C_EVAL = 261, C_SHELL = 262, - T_DIGITS = 263, - T_LITERAL = 264, - T_METHOD = 265, - T_OPLINE = 266, - T_FILE = 267, - T_ID = 268, - T_INPUT = 269, - T_UNEXPECTED = 270 + C_IF = 263, + T_DIGITS = 264, + T_LITERAL = 265, + T_METHOD = 266, + T_OPLINE = 267, + T_FILE = 268, + T_ID = 269, + T_INPUT = 270, + T_UNEXPECTED = 271 }; #endif From d9801018035ac61fd0d923fc4c24eb98cc41d0e8 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 17 Feb 2014 22:43:53 +0000 Subject: [PATCH 050/137] start work on resolving commands, add numeric function and method to lexer --- dev/phpdbg_lexer.l | 56 +++--- dev/phpdbg_parser.y | 129 +++++++++++--- phpdbg_lexer.c | 410 +++++++++++++++++++++++--------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 265 ++++++++++++++++++---------- phpdbg_parser.h | 14 +- 6 files changed, 540 insertions(+), 336 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 76c28c45dd6..bf74cbdc681 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -21,27 +21,29 @@ %option reentrant noyywrap never-interactive nounistd %option bison-bridge -C_TRUE ?i:"true" -C_YES ?i:"yes" -C_ON ?i:"on" -C_ENABLED ?i:"enabled" -C_FALSE ?i:"false" -C_NO ?i:"no" -C_OFF ?i:"off" -C_DISABLED ?i:"disabled" -C_EVAL ?i:"eval" -C_SHELL ?i:"shell" -C_IF ?i:"if" +C_TRUE ?i:"true" +C_YES ?i:"yes" +C_ON ?i:"on" +C_ENABLED ?i:"enabled" +C_FALSE ?i:"false" +C_NO ?i:"no" +C_OFF ?i:"off" +C_DISABLED ?i:"disabled" +C_EVAL ?i:"eval" +C_SHELL ?i:"shell" +C_IF ?i:"if" -DIGITS [0-9]+ -ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-]* -NSID [\\\\]?{ID} -METHOD {NSID}+::{ID} -FILE [^ :]+:[0-9]+ -OPLINE 0x[a-fA-F0-9]+ -LITERAL \"(\\.|[^\\"])*\" -WS [ \r\n\t]+ -INPUT [^\n]+ +DIGITS [0-9]+ +ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-]* +NSID [\\\\]?{ID} +METHOD {NSID}+::{ID} +NUMERIC_METHOD {METHOD}[#]{DIGITS} +NUMERIC_FUNCTION {NSID}[#]{DIGITS} +FILE [^ :]+:[0-9]+ +OPLINE 0x[a-fA-F0-9]+ +LITERAL \"(\\.|[^\\"])*\" +WS [ \r\n\t]+ +INPUT [^\n]+ %% { @@ -75,6 +77,20 @@ INPUT [^\n]+ yylval->num = atoi(yytext); return T_DIGITS; } + {NUMERIC_METHOD} { + phpdbg_init_param(yylval, NUMERIC_METHOD_PARAM); + yylval->method.class = "class"; + yylval->method.name = "func"; + yylval->num = 0; + return T_METHOD; + } + {NUMERIC_FUNCTION} { + phpdbg_init_param(yylval, NUMERIC_FUNCTION_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + yylval->num = 0; + return T_ID; + } {METHOD} { phpdbg_init_param(yylval, METHOD_PARAM); yylval->method.class = "class"; diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 185283eb8e1..9d7149ff83f 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -11,6 +11,7 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_prompt.h" #define YYSTYPE phpdbg_param_t @@ -42,6 +43,14 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; + case NUMERIC_METHOD_PARAM: + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); + break; + case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; @@ -102,13 +111,69 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { next->top = stack->top; stack->top = next; } - + phpdbg_debug_param(next, "push ->"); stack->len++; } +phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { + const phpdbg_command_t *command = commands; + phpdbg_param_t *name = *top; + phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; + ulong matches = 0L; + + while (command && command->name && command->handler) { + if (command->name_len >= name->len) { + if (memcmp(command->name, name->str, name->len) == SUCCESS) { + if (matches < 3) { + matched[matches] = command; + matches++; + } else break; + } + } + command++; + } + + switch (matches) { + case 0: { + asprintf( + why, + "The command %s could not be found", + name->str); + } break; + + case 1: { + (*top) = (*top)->next; + if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { + command = phpdbg_stack_resolve(matched[0]->subs, top, why); + if (command) { + phpdbg_notice( + "Command matching with sub command %s %s", + matched[0]->name, command->name); + return command; + } + } + + phpdbg_notice( + "Command matching with %s", + matched[0]->name); + return matched[0]; + } break; + + default: { + asprintf( + why, + "The command %s is ambigious, matching %d commands", + name->str, matches); + } + } + + return NULL; +} + int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { phpdbg_param_t *command = NULL, *params = NULL; + phpdbg_command_t *handler = NULL; if (stack->type != STACK_PARAM) { asprintf( @@ -122,7 +187,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return FAILURE; } - command = params = (phpdbg_param_t*) stack->next; + command = (phpdbg_param_t*) stack->next; switch (command->type) { case EVAL_PARAM: @@ -135,6 +200,23 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { case STR_PARAM: { /* do resolve command(s) */ + handler = phpdbg_stack_resolve( + phpdbg_prompt_commands, &command, why); + + if (handler) { + /* get top of stack */ + params = command; + + /* prepare params */ + while (params) { + phpdbg_debug_param(params, "-> ..."); + params = params->next; + } + + return SUCCESS; + } else { + return FAILURE; + } } break; default: @@ -143,13 +225,6 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return FAILURE; } - /* do prepare params for function */ - - while (params) { - phpdbg_debug_param(params, "-> ..."); - params = params->next; - } - return SUCCESS; } @@ -163,7 +238,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { typedef void* yyscan_t; #endif } -%expect 1 +%expect 1 %output "sapi/phpdbg/phpdbg_parser.c" %defines "sapi/phpdbg/phpdbg_parser.h" @@ -179,14 +254,16 @@ typedef void* yyscan_t; %token C_SHELL "shell" %token C_IF "if (condition)" -%token T_DIGITS "digits (numbers)" -%token T_LITERAL "literal (string)" -%token T_METHOD "method" -%token T_OPLINE "opline" -%token T_FILE "file" -%token T_ID "identifier (command or function name)" -%token T_INPUT "input (input string or data)" -%token T_UNEXPECTED "input" +%token T_DIGITS "digits (numbers)" +%token T_LITERAL "literal (string)" +%token T_METHOD "method" +%token T_NUMERIC_METHOD "method opline address" +%token T_NUMERIC_FUNCTION "function opline address" +%token T_OPLINE "opline" +%token T_FILE "file" +%token T_ID "identifier (command or function name)" +%token T_INPUT "input (input string or data)" +%token T_UNEXPECTED "input" %% input @@ -199,22 +276,22 @@ parameters ; params - : /* empty */ - | parameters + : parameters + | /* empty */ ; normal - : T_ID { $$ = $1; } - | normal T_ID { $$ = $2; } + : T_ID { phpdbg_stack_push(stack, &$1); } + | normal T_ID { phpdbg_stack_push(stack, &$2); } ; special - : C_EVAL T_INPUT { $$ = $2; $$.type = EVAL_PARAM; } - | C_SHELL T_INPUT { $$ = $2; $$.type = SHELL_PARAM;; } + : C_EVAL T_INPUT { $$ = $2; $$.type = EVAL_PARAM; } + | C_SHELL T_INPUT { $$ = $2; $$.type = SHELL_PARAM; } ; command - : normal { phpdbg_stack_push(stack, &$1); } + : normal | special { phpdbg_stack_push(stack, &$1); } ; @@ -222,6 +299,8 @@ parameter : T_DIGITS { $$ = $1; } | T_FILE { $$ = $1; } | T_METHOD { $$ = $1; } + | T_NUMERIC_METHOD { $$ = $1; } + | T_NUMERIC_FUNCTION { $$ = $1; } | T_OPLINE { $$ = $1; } | T_ID { $$ = $1; } | T_LITERAL { $$ = $1; } diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index cc8535fe5c6..e9e243c5e55 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,18 +358,18 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[92] = +static yyconst flex_int16_t yy_accept[96] = { 0, - 0, 0, 0, 0, 16, 14, 13, 13, 13, 14, - 11, 6, 6, 14, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 14, 12, 12, 13, 0, 0, 13, - 13, 0, 0, 10, 0, 0, 11, 11, 0, 0, - 6, 0, 11, 11, 11, 11, 3, 5, 11, 4, - 11, 11, 11, 11, 12, 12, 8, 10, 0, 8, - 0, 0, 9, 11, 11, 11, 11, 5, 11, 11, - 4, 7, 0, 0, 11, 11, 1, 11, 11, 4, - 7, 11, 11, 5, 2, 11, 11, 11, 4, 5, - 0 + 0, 0, 0, 0, 18, 16, 15, 15, 15, 16, + 13, 6, 6, 16, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 16, 14, 14, 15, 0, 0, 15, + 15, 0, 0, 12, 0, 0, 0, 13, 13, 0, + 0, 6, 0, 13, 13, 13, 13, 3, 5, 13, + 4, 13, 13, 13, 13, 14, 14, 10, 12, 0, + 10, 8, 0, 0, 11, 13, 13, 13, 13, 5, + 13, 13, 4, 9, 0, 0, 13, 13, 1, 13, + 13, 4, 0, 9, 13, 13, 5, 2, 7, 13, + 13, 13, 4, 5, 0 } ; @@ -378,184 +378,184 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 1, 5, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 6, 1, 1, 7, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, - 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, - 6, 16, 17, 6, 6, 18, 6, 19, 20, 6, - 6, 21, 22, 23, 24, 25, 6, 6, 26, 6, - 1, 27, 1, 1, 6, 1, 28, 29, 12, 30, + 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 7, 1, 1, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 10, 1, 1, + 1, 1, 1, 1, 11, 12, 13, 14, 15, 16, + 7, 17, 18, 7, 7, 19, 7, 20, 21, 7, + 7, 22, 23, 24, 25, 26, 7, 7, 27, 7, + 1, 28, 1, 1, 7, 1, 29, 30, 13, 31, - 31, 32, 6, 33, 34, 6, 6, 35, 6, 36, - 37, 6, 6, 38, 39, 40, 41, 42, 6, 43, - 44, 6, 1, 1, 1, 1, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 32, 33, 7, 34, 35, 7, 7, 36, 7, 37, + 38, 7, 7, 39, 40, 41, 42, 43, 7, 44, + 45, 7, 1, 1, 1, 1, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6 + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7 } ; -static yyconst flex_int32_t yy_meta[45] = +static yyconst flex_int32_t yy_meta[46] = { 0, - 1, 1, 2, 3, 1, 4, 5, 5, 1, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 1, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4 + 1, 1, 2, 3, 1, 4, 5, 4, 4, 1, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 1, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5 } ; -static yyconst flex_int16_t yy_base[103] = +static yyconst flex_int16_t yy_base[107] = { 0, - 0, 0, 43, 46, 161, 150, 49, 52, 60, 61, - 88, 60, 64, 433, 115, 58, 70, 42, 65, 93, - 97, 116, 121, 155, 0, 103, 137, 125, 71, 142, - 163, 164, 116, 77, 167, 144, 67, 92, 169, 194, - 172, 215, 166, 176, 203, 172, 94, 102, 200, 153, - 202, 218, 231, 175, 0, 236, 177, 433, 78, 249, - 0, 276, 0, 241, 238, 256, 265, 246, 271, 278, - 276, 0, 312, 339, 316, 290, 277, 318, 319, 284, - 0, 338, 343, 309, 317, 344, 346, 351, 345, 348, - 433, 385, 390, 395, 400, 405, 410, 415, 420, 56, + 0, 0, 44, 47, 160, 136, 50, 53, 62, 57, + 85, 60, 63, 433, 113, 63, 91, 64, 89, 112, + 41, 90, 118, 153, 0, 75, 135, 101, 126, 162, + 140, 147, 112, 95, 162, 170, 168, 66, 150, 174, + 190, 178, 211, 171, 199, 218, 195, 197, 198, 219, + 220, 230, 221, 241, 231, 0, 199, 196, 433, 100, + 252, 199, 0, 281, 0, 240, 267, 259, 270, 232, + 280, 285, 278, 90, 320, 0, 289, 314, 296, 319, + 317, 309, 262, 86, 320, 325, 323, 324, 264, 346, + 348, 349, 347, 350, 433, 385, 390, 395, 400, 405, - 425, 427 + 410, 415, 420, 69, 425, 427 } ; -static yyconst flex_int16_t yy_def[103] = +static yyconst flex_int16_t yy_def[107] = { 0, - 91, 1, 92, 92, 91, 93, 93, 93, 91, 94, - 95, 93, 93, 91, 95, 15, 15, 15, 15, 15, - 15, 15, 15, 96, 97, 97, 91, 93, 91, 93, - 91, 94, 98, 93, 98, 94, 15, 15, 91, 99, - 93, 93, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 97, 97, 91, 91, 98, 98, - 100, 101, 42, 15, 15, 15, 15, 15, 15, 15, - 15, 102, 101, 101, 15, 15, 15, 15, 15, 15, - 102, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 95, 1, 96, 96, 95, 97, 97, 97, 95, 98, + 99, 97, 97, 95, 99, 15, 15, 15, 15, 15, + 15, 15, 15, 100, 101, 101, 95, 97, 95, 97, + 95, 98, 102, 97, 102, 98, 97, 15, 15, 95, + 103, 97, 97, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 101, 101, 95, 95, 102, + 102, 97, 104, 105, 43, 15, 15, 15, 15, 15, + 15, 15, 15, 106, 105, 75, 15, 15, 15, 15, + 15, 15, 95, 106, 15, 15, 15, 15, 95, 15, + 15, 15, 15, 15, 0, 95, 95, 95, 95, 95, - 91, 91 + 95, 95, 95, 95, 95, 95 } ; -static yyconst flex_int16_t yy_nxt[478] = +static yyconst flex_int16_t yy_nxt[479] = { 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 11, - 11, 11, 15, 16, 17, 11, 18, 11, 19, 20, - 11, 21, 22, 11, 11, 23, 24, 11, 11, 15, - 16, 17, 11, 18, 11, 19, 20, 11, 21, 22, - 11, 11, 11, 23, 26, 27, 26, 26, 27, 26, - 30, 30, 31, 30, 30, 31, 47, 29, 37, 72, - 29, 31, 31, 31, 33, 34, 41, 41, 29, 35, - 41, 41, 29, 47, 37, 37, 44, 57, 57, 46, - 91, 37, 45, 37, 48, 29, 37, 36, 28, 28, - 28, 37, 28, 44, 38, 38, 39, 46, 37, 45, + 6, 7, 8, 9, 10, 6, 11, 12, 13, 14, + 11, 11, 11, 15, 16, 17, 11, 18, 11, 19, + 20, 11, 21, 22, 11, 11, 23, 24, 11, 11, + 15, 16, 17, 11, 18, 11, 19, 20, 11, 21, + 22, 11, 11, 11, 23, 26, 27, 26, 26, 27, + 26, 30, 30, 31, 30, 30, 31, 52, 38, 29, + 33, 34, 29, 31, 31, 31, 35, 42, 42, 29, + 42, 42, 29, 74, 52, 38, 57, 31, 57, 48, + 38, 38, 45, 38, 36, 28, 28, 28, 46, 28, + 37, 83, 39, 39, 40, 83, 48, 38, 38, 45, - 37, 48, 42, 37, 56, 31, 56, 49, 37, 37, - 37, 50, 51, 37, 40, 28, 28, 28, 37, 28, - 58, 38, 38, 39, 49, 37, 37, 37, 50, 51, - 37, 43, 37, 29, 53, 37, 52, 37, 31, 31, - 31, 40, 59, 30, 30, 31, 28, 33, 43, 37, - 29, 53, 35, 52, 37, 28, 28, 28, 29, 28, - 91, 28, 28, 29, 31, 31, 31, 33, 34, 37, - 91, 58, 35, 60, 60, 57, 57, 61, 41, 41, - 29, 28, 37, 57, 57, 65, 37, 64, 37, 67, - 36, 37, 37, 59, 28, 28, 28, 91, 28, 37, + 38, 47, 95, 43, 29, 46, 38, 38, 38, 49, + 29, 53, 41, 28, 28, 28, 59, 28, 37, 47, + 39, 39, 40, 38, 38, 38, 49, 50, 53, 38, + 44, 51, 54, 58, 58, 38, 31, 31, 31, 60, + 41, 31, 31, 31, 50, 29, 38, 44, 51, 54, + 33, 34, 38, 28, 28, 28, 35, 28, 28, 95, + 28, 28, 29, 30, 30, 31, 59, 38, 95, 61, + 61, 29, 28, 33, 36, 62, 62, 29, 95, 35, + 28, 58, 58, 63, 38, 42, 42, 29, 38, 60, + 28, 28, 28, 66, 28, 28, 95, 28, 28, 29, - 28, 28, 29, 65, 64, 37, 67, 91, 37, 37, - 91, 91, 66, 91, 68, 69, 37, 91, 37, 37, - 28, 63, 63, 29, 63, 63, 63, 63, 63, 63, - 66, 68, 69, 37, 37, 37, 37, 56, 31, 56, - 91, 70, 63, 63, 63, 63, 63, 37, 76, 91, - 75, 37, 71, 58, 37, 60, 60, 37, 70, 91, - 91, 91, 37, 91, 37, 91, 76, 91, 75, 71, - 91, 37, 37, 77, 37, 59, 28, 28, 28, 37, - 28, 37, 74, 74, 39, 91, 78, 37, 79, 37, - 77, 80, 37, 37, 37, 91, 91, 91, 37, 91, + 57, 31, 57, 58, 58, 38, 62, 62, 29, 67, + 66, 95, 38, 69, 38, 38, 38, 28, 65, 65, + 29, 65, 65, 65, 65, 65, 65, 67, 68, 38, + 69, 38, 38, 38, 70, 38, 38, 38, 38, 65, + 65, 65, 65, 65, 71, 72, 68, 38, 38, 38, + 77, 70, 38, 38, 38, 38, 59, 38, 38, 61, + 61, 71, 72, 73, 38, 38, 38, 95, 77, 89, + 89, 89, 89, 95, 38, 38, 38, 79, 78, 60, + 73, 28, 28, 28, 38, 28, 28, 38, 76, 76, + 40, 95, 80, 38, 79, 38, 78, 38, 81, 82, - 37, 91, 40, 78, 37, 79, 37, 83, 80, 37, - 37, 37, 28, 28, 28, 91, 28, 37, 74, 74, - 39, 91, 91, 37, 83, 37, 82, 91, 91, 91, - 91, 84, 37, 37, 37, 37, 85, 91, 40, 28, - 28, 28, 37, 28, 82, 74, 74, 39, 84, 37, - 37, 37, 37, 85, 37, 86, 87, 88, 89, 37, - 37, 37, 37, 90, 37, 40, 91, 37, 91, 91, - 91, 37, 86, 87, 88, 89, 37, 37, 37, 37, - 90, 37, 91, 91, 37, 25, 25, 25, 25, 25, - 28, 28, 91, 28, 28, 32, 32, 32, 32, 32, + 85, 38, 38, 95, 38, 95, 38, 95, 41, 80, + 95, 95, 38, 38, 38, 81, 82, 95, 85, 38, + 28, 28, 28, 38, 28, 28, 38, 76, 76, 40, + 38, 38, 86, 87, 38, 88, 38, 38, 90, 91, + 38, 38, 38, 38, 95, 95, 95, 41, 38, 86, + 87, 38, 88, 38, 38, 90, 91, 38, 38, 38, + 92, 93, 94, 38, 38, 38, 38, 38, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 92, 93, 94, + 38, 38, 38, 38, 38, 25, 25, 25, 25, 25, + 28, 28, 95, 28, 28, 32, 32, 32, 32, 32, - 37, 37, 91, 37, 37, 54, 54, 91, 54, 54, - 55, 91, 55, 55, 55, 33, 33, 33, 33, 33, - 62, 62, 91, 62, 62, 73, 73, 91, 73, 73, - 81, 81, 5, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91 + 38, 38, 95, 38, 38, 55, 55, 95, 55, 55, + 56, 95, 56, 56, 56, 33, 33, 33, 33, 33, + 64, 64, 95, 64, 64, 75, 75, 95, 75, 75, + 84, 84, 5, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95 } ; -static yyconst flex_int16_t yy_chk[478] = +static yyconst flex_int16_t yy_chk[479] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, - 7, 7, 7, 8, 8, 8, 18, 7, 18, 100, - 8, 9, 9, 9, 10, 10, 12, 12, 12, 10, - 13, 13, 13, 18, 16, 18, 16, 29, 29, 17, - 59, 19, 16, 37, 19, 34, 17, 10, 11, 11, - 11, 16, 11, 16, 11, 11, 11, 17, 19, 16, + 1, 1, 1, 1, 1, 3, 3, 3, 4, 4, + 4, 7, 7, 7, 8, 8, 8, 21, 21, 7, + 10, 10, 8, 9, 9, 9, 10, 12, 12, 12, + 13, 13, 13, 104, 21, 21, 26, 26, 26, 18, + 16, 18, 16, 38, 10, 11, 11, 11, 16, 11, + 11, 84, 11, 11, 11, 74, 18, 16, 18, 16, - 37, 19, 12, 17, 26, 26, 26, 20, 38, 20, - 47, 20, 21, 21, 11, 15, 15, 15, 48, 15, - 33, 15, 15, 15, 20, 38, 20, 47, 20, 21, - 21, 15, 22, 28, 23, 48, 22, 23, 27, 27, - 27, 15, 33, 30, 30, 30, 36, 36, 15, 22, - 30, 23, 36, 22, 23, 24, 24, 24, 6, 24, - 5, 24, 24, 24, 31, 31, 31, 32, 32, 50, - 0, 35, 32, 35, 35, 39, 39, 39, 41, 41, - 41, 24, 43, 57, 57, 44, 50, 43, 46, 46, - 32, 54, 44, 35, 40, 40, 40, 0, 40, 43, + 38, 17, 60, 12, 34, 16, 19, 22, 17, 19, + 28, 22, 11, 15, 15, 15, 33, 15, 15, 17, + 15, 15, 15, 19, 22, 17, 19, 20, 22, 20, + 15, 20, 23, 29, 29, 23, 27, 27, 27, 33, + 15, 31, 31, 31, 20, 6, 20, 15, 20, 23, + 32, 32, 23, 24, 24, 24, 32, 24, 24, 5, + 24, 24, 24, 30, 30, 30, 35, 39, 0, 35, + 35, 30, 36, 36, 32, 37, 37, 37, 0, 36, + 24, 40, 40, 40, 39, 42, 42, 42, 44, 35, + 41, 41, 41, 44, 41, 41, 0, 41, 41, 41, - 40, 40, 40, 44, 43, 46, 46, 0, 54, 44, - 0, 0, 45, 0, 49, 51, 49, 0, 51, 45, - 40, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 45, 49, 51, 49, 52, 51, 45, 56, 56, 56, - 0, 52, 42, 42, 42, 42, 42, 53, 65, 0, - 64, 52, 53, 60, 65, 60, 60, 64, 52, 0, - 0, 0, 68, 0, 53, 0, 65, 0, 64, 53, - 0, 65, 66, 66, 64, 60, 62, 62, 62, 68, - 62, 67, 62, 62, 62, 0, 67, 69, 69, 66, - 66, 70, 71, 77, 70, 0, 0, 0, 67, 0, + 57, 57, 57, 58, 58, 44, 62, 62, 62, 45, + 44, 0, 47, 47, 48, 49, 45, 41, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 45, 46, 47, + 47, 48, 49, 45, 50, 46, 50, 51, 53, 43, + 43, 43, 43, 43, 52, 53, 46, 52, 55, 70, + 66, 50, 46, 50, 51, 53, 61, 66, 54, 61, + 61, 52, 53, 54, 52, 55, 70, 0, 66, 83, + 83, 89, 89, 0, 66, 54, 68, 68, 67, 61, + 54, 64, 64, 64, 67, 64, 64, 69, 64, 64, + 64, 0, 69, 68, 68, 73, 67, 71, 71, 72, - 80, 0, 62, 67, 69, 69, 76, 76, 70, 71, - 77, 70, 73, 73, 73, 0, 73, 80, 73, 73, - 73, 0, 0, 76, 76, 84, 75, 0, 0, 0, - 0, 78, 75, 85, 78, 79, 79, 0, 73, 74, - 74, 74, 84, 74, 75, 74, 74, 74, 78, 75, - 85, 78, 79, 79, 82, 82, 83, 86, 87, 83, - 86, 89, 87, 88, 90, 74, 0, 88, 0, 0, - 0, 82, 82, 83, 86, 87, 83, 86, 89, 87, - 88, 90, 0, 0, 88, 92, 92, 92, 92, 92, - 93, 93, 0, 93, 93, 94, 94, 94, 94, 94, + 77, 67, 72, 0, 69, 0, 77, 0, 64, 69, + 0, 0, 73, 79, 71, 71, 72, 0, 77, 72, + 75, 75, 75, 77, 75, 75, 82, 75, 75, 75, + 79, 78, 78, 80, 81, 81, 80, 85, 85, 86, + 87, 88, 86, 82, 0, 0, 0, 75, 78, 78, + 80, 81, 81, 80, 85, 85, 86, 87, 88, 86, + 90, 91, 92, 90, 93, 91, 92, 94, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, + 90, 93, 91, 92, 94, 96, 96, 96, 96, 96, + 97, 97, 0, 97, 97, 98, 98, 98, 98, 98, - 95, 95, 0, 95, 95, 96, 96, 0, 96, 96, - 97, 0, 97, 97, 97, 98, 98, 98, 98, 98, - 99, 99, 0, 99, 99, 101, 101, 0, 101, 101, - 102, 102, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91 + 99, 99, 0, 99, 99, 100, 100, 0, 100, 100, + 101, 0, 101, 101, 101, 102, 102, 102, 102, 102, + 103, 103, 0, 103, 103, 105, 105, 0, 105, 105, + 106, 106, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95 } ; /* The intent behind this definition is that it'll catch @@ -819,7 +819,7 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 825 "sapi/phpdbg/phpdbg_lexer.c" @@ -876,13 +876,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 92 ) + if ( yy_current_state >= 96 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 91 ); + while ( yy_current_state != 95 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -904,7 +904,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 50 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -913,7 +913,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 53 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -922,7 +922,7 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 58 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -931,7 +931,7 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 65 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -940,7 +940,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 70 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; @@ -949,7 +949,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 75 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -958,7 +958,29 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 80 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_METHOD_PARAM); + yylval->method.class = "class"; + yylval->method.name = "func"; + yylval->num = 0; + return T_METHOD; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 87 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_FUNCTION_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + yylval->num = 0; + return T_ID; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 94 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, METHOD_PARAM); yylval->method.class = "class"; @@ -966,10 +988,10 @@ YY_RULE_SETUP return T_METHOD; } YY_BREAK -case 8: -/* rule 8 can match eol */ +case 10: +/* rule 10 can match eol */ YY_RULE_SETUP -#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 100 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, FILE_PARAM); yylval->file.name = strndup(yytext, yyleng); @@ -977,19 +999,19 @@ YY_RULE_SETUP return T_FILE; } YY_BREAK -case 9: +case 11: YY_RULE_SETUP -#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } YY_BREAK -case 10: -/* rule 10 can match eol */ +case 12: +/* rule 12 can match eol */ YY_RULE_SETUP -#line 95 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -997,9 +1019,9 @@ YY_RULE_SETUP return T_LITERAL; } YY_BREAK -case 11: +case 13: YY_RULE_SETUP -#line 101 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 117 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1008,9 +1030,9 @@ YY_RULE_SETUP } YY_BREAK -case 12: +case 14: YY_RULE_SETUP -#line 108 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 124 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1019,26 +1041,26 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 13: -/* rule 13 can match eol */ +case 15: +/* rule 15 can match eol */ YY_RULE_SETUP -#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 131 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 14: +case 16: YY_RULE_SETUP -#line 116 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, EMPTY_PARAM); return T_UNEXPECTED; } YY_BREAK -case 15: +case 17: YY_RULE_SETUP -#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1042 "sapi/phpdbg/phpdbg_lexer.c" +#line 1064 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1334,7 +1356,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 92 ) + if ( yy_current_state >= 96 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1363,11 +1385,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 92 ) + if ( yy_current_state >= 96 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 91); + yy_is_jam = (yy_current_state == 95); return yy_is_jam ? 0 : yy_current_state; } @@ -2203,7 +2225,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index b835a6695e1..40e64e159e3 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index fee118564d3..ef9d4f43335 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -79,6 +79,7 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_prompt.h" #define YYSTYPE phpdbg_param_t @@ -110,6 +111,14 @@ void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); break; + case NUMERIC_METHOD_PARAM: + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); + break; + case NUMERIC_PARAM: fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); break; @@ -170,13 +179,69 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { next->top = stack->top; stack->top = next; } - + phpdbg_debug_param(next, "push ->"); stack->len++; } +phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { + const phpdbg_command_t *command = commands; + phpdbg_param_t *name = *top; + phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; + ulong matches = 0L; + + while (command && command->name && command->handler) { + if (command->name_len >= name->len) { + if (memcmp(command->name, name->str, name->len) == SUCCESS) { + if (matches < 3) { + matched[matches] = command; + matches++; + } else break; + } + } + command++; + } + + switch (matches) { + case 0: { + asprintf( + why, + "The command %s could not be found", + name->str); + } break; + + case 1: { + (*top) = (*top)->next; + if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { + command = phpdbg_stack_resolve(matched[0]->subs, top, why); + if (command) { + phpdbg_notice( + "Command matching with sub command %s %s", + matched[0]->name, command->name); + return command; + } + } + + phpdbg_notice( + "Command matching with %s", + matched[0]->name); + return matched[0]; + } break; + + default: { + asprintf( + why, + "The command %s is ambigious, matching %d commands", + name->str, matches); + } + } + + return NULL; +} + int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { phpdbg_param_t *command = NULL, *params = NULL; + phpdbg_command_t *handler = NULL; if (stack->type != STACK_PARAM) { asprintf( @@ -190,7 +255,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return FAILURE; } - command = params = (phpdbg_param_t*) stack->next; + command = (phpdbg_param_t*) stack->next; switch (command->type) { case EVAL_PARAM: @@ -203,6 +268,23 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { case STR_PARAM: { /* do resolve command(s) */ + handler = phpdbg_stack_resolve( + phpdbg_prompt_commands, &command, why); + + if (handler) { + /* get top of stack */ + params = command; + + /* prepare params */ + while (params) { + phpdbg_debug_param(params, "-> ..."); + params = params->next; + } + + return SUCCESS; + } else { + return FAILURE; + } } break; default: @@ -211,13 +293,6 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return FAILURE; } - /* do prepare params for function */ - - while (params) { - phpdbg_debug_param(params, "-> ..."); - params = params->next; - } - return SUCCESS; } @@ -225,7 +300,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* Line 268 of yacc.c */ -#line 229 "sapi/phpdbg/phpdbg_parser.c" +#line 304 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -248,7 +323,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 159 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 234 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -259,7 +334,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 263 "sapi/phpdbg/phpdbg_parser.c" +#line 338 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -276,11 +351,13 @@ typedef void* yyscan_t; T_DIGITS = 264, T_LITERAL = 265, T_METHOD = 266, - T_OPLINE = 267, - T_FILE = 268, - T_ID = 269, - T_INPUT = 270, - T_UNEXPECTED = 271 + T_NUMERIC_METHOD = 267, + T_NUMERIC_FUNCTION = 268, + T_OPLINE = 269, + T_FILE = 270, + T_ID = 271, + T_INPUT = 272, + T_UNEXPECTED = 273 }; #endif @@ -298,7 +375,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 302 "sapi/phpdbg/phpdbg_parser.c" +#line 379 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -517,20 +594,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 20 +#define YYLAST 24 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 17 +#define YYNTOKENS 19 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 9 /* YYNRULES -- Number of rules. */ -#define YYNRULES 22 +#define YYNRULES 24 /* YYNRULES -- Number of states. */ -#define YYNSTATES 27 +#define YYNSTATES 29 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 271 +#define YYMAXUTOK 273 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -565,7 +642,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16 + 15, 16, 17, 18 }; #if YYDEBUG @@ -573,27 +650,28 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 7, 10, 11, 13, 15, 18, + 0, 0, 3, 5, 7, 10, 12, 13, 15, 18, 21, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 47 + 42, 44, 46, 48, 51 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 18, 0, -1, 25, -1, 24, -1, 19, 24, -1, - -1, 19, -1, 14, -1, 21, 14, -1, 6, 15, - -1, 7, 15, -1, 21, -1, 22, -1, 9, -1, - 13, -1, 11, -1, 12, -1, 14, -1, 10, -1, - 3, -1, 4, -1, 8, 15, -1, 23, 20, -1 + 20, 0, -1, 27, -1, 26, -1, 21, 26, -1, + 21, -1, -1, 16, -1, 23, 16, -1, 6, 17, + -1, 7, 17, -1, 23, -1, 24, -1, 9, -1, + 15, -1, 11, -1, 12, -1, 13, -1, 14, -1, + 16, -1, 10, -1, 3, -1, 4, -1, 8, 17, + -1, 25, 22, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = +static const yytype_uint16 yyrline[] = { - 0, 193, 193, 197, 198, 201, 203, 207, 208, 212, - 213, 217, 218, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 234 + 0, 270, 270, 274, 275, 279, 280, 284, 285, 289, + 290, 294, 295, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 313 }; #endif @@ -606,8 +684,8 @@ static const char *const yytname[] = "\"falsy (false, off, no or disabled)\"", "\"string (some input, perhaps)\"", "\"eval\"", "\"shell\"", "\"if (condition)\"", "\"digits (numbers)\"", "\"literal (string)\"", - "\"method\"", "\"opline\"", "\"file\"", - "\"identifier (command or function name)\"", + "\"method\"", "\"method opline address\"", "\"function opline address\"", + "\"opline\"", "\"file\"", "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", "parameters", "params", "normal", "special", "command", "parameter", "handler", 0 @@ -620,24 +698,24 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271 + 265, 266, 267, 268, 269, 270, 271, 272, 273 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 17, 18, 19, 19, 20, 20, 21, 21, 22, - 22, 23, 23, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 25 + 0, 19, 20, 21, 21, 22, 22, 23, 23, 24, + 24, 25, 25, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 1, 2, 0, 1, 1, 2, 2, + 0, 2, 1, 1, 2, 1, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2 + 1, 1, 1, 2, 2 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -645,31 +723,31 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 7, 0, 11, 12, 5, 2, 9, - 10, 1, 8, 19, 20, 0, 13, 18, 15, 16, - 14, 17, 6, 22, 3, 21, 4 + 0, 0, 0, 7, 0, 11, 12, 6, 2, 9, + 10, 1, 8, 21, 22, 0, 13, 20, 15, 16, + 17, 18, 14, 19, 5, 24, 3, 23, 4 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 4, 22, 23, 5, 6, 7, 24, 8 + -1, 4, 24, 25, 5, 6, 7, 26, 8 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -14 +#define YYPACT_NINF -16 static const yytype_int8 yypact[] = { - 6, -13, -12, -14, 4, 0, -14, -3, -14, -14, - -14, -14, -14, -14, -14, 1, -14, -14, -14, -14, - -14, -14, -3, -14, -14, -14, -14 + 8, -15, -14, -16, 4, 0, -16, -3, -16, -16, + -16, -16, -16, -16, -16, 1, -16, -16, -16, -16, + -16, -16, -16, -16, -3, -16, -16, -16, -16 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -14, -14, -14, -14, -14, -14, -14, -7, -14 + -16, -16, -16, -16, -16, -16, -16, -7, -16 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -679,30 +757,30 @@ static const yytype_int8 yypgoto[] = static const yytype_uint8 yytable[] = { 13, 14, 9, 10, 11, 15, 16, 17, 18, 19, - 20, 21, 1, 2, 12, 26, 25, 0, 0, 0, - 3 + 20, 21, 22, 23, 1, 2, 12, 28, 27, 0, + 0, 0, 0, 0, 3 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-14)) + ((yystate) == (-16)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 15, 15, 0, 8, 9, 10, 11, 12, - 13, 14, 6, 7, 14, 22, 15, -1, -1, -1, - 14 + 3, 4, 17, 17, 0, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 6, 7, 16, 24, 17, -1, + -1, -1, -1, -1, 16 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 6, 7, 14, 18, 21, 22, 23, 25, 15, - 15, 0, 14, 3, 4, 8, 9, 10, 11, 12, - 13, 14, 19, 20, 24, 15, 24 + 0, 6, 7, 16, 20, 23, 24, 25, 27, 17, + 17, 0, 16, 3, 4, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 21, 22, 26, 17, 26 }; #define yyerrok (yyerrstatus = 0) @@ -1551,126 +1629,133 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 197 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 274 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 198 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 275 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 207 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } +#line 284 "sapi/phpdbg/dev/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 208 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); } +#line 285 "sapi/phpdbg/dev/phpdbg_parser.y" + { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 212 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } +#line 289 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } break; case 10: /* Line 1806 of yacc.c */ -#line 213 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM;; } - break; - - case 11: - -/* Line 1806 of yacc.c */ -#line 217 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } +#line 290 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } break; case 12: /* Line 1806 of yacc.c */ -#line 218 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 295 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 222 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 299 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 223 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 300 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 224 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 301 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 225 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 302 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 226 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 303 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 227 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 304 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 228 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 305 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 229 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 306 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: /* Line 1806 of yacc.c */ -#line 230 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 307 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 22: + +/* Line 1806 of yacc.c */ +#line 308 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 23: + +/* Line 1806 of yacc.c */ +#line 309 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } break; /* Line 1806 of yacc.c */ -#line 1674 "sapi/phpdbg/phpdbg_parser.c" +#line 1759 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1901,6 +1986,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 236 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 315 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index d3ba58aa70e..612982c46fa 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 159 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 234 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -61,11 +61,13 @@ typedef void* yyscan_t; T_DIGITS = 264, T_LITERAL = 265, T_METHOD = 266, - T_OPLINE = 267, - T_FILE = 268, - T_ID = 269, - T_INPUT = 270, - T_UNEXPECTED = 271 + T_NUMERIC_METHOD = 267, + T_NUMERIC_FUNCTION = 268, + T_OPLINE = 269, + T_FILE = 270, + T_ID = 271, + T_INPUT = 272, + T_UNEXPECTED = 273 }; #endif From cadc909bb73eaf13108e55e7f7b5d64df812cf4e Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 08:39:38 +0000 Subject: [PATCH 051/137] use correct param types --- dev/phpdbg_parser.y | 5 ++--- phpdbg_parser.c | 4 ++-- phpdbg_prompt.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 9d7149ff83f..24bcc685372 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -191,11 +191,11 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (command->type) { case EVAL_PARAM: - phpdbg_notice("eval (%s)", command->str); + PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); break; case SHELL_PARAM: - phpdbg_notice("shell (%s)", command->str); + PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); break; case STR_PARAM: { @@ -228,7 +228,6 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return SUCCESS; } - %} %code requires { diff --git a/phpdbg_parser.c b/phpdbg_parser.c index ef9d4f43335..79745cef8be 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -259,11 +259,11 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (command->type) { case EVAL_PARAM: - phpdbg_notice("eval (%s)", command->str); + PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); break; case SHELL_PARAM: - phpdbg_notice("shell (%s)", command->str); + PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); break; case STR_PARAM: { diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index e53a5e68b19..632ceb97611 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -617,7 +617,7 @@ out: PHPDBG_COMMAND(eval) /* {{{ */ { switch (param->type) { - case STR_PARAM: { + case EVAL_PARAM: { zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); zval retval; @@ -780,7 +780,7 @@ PHPDBG_COMMAND(shell) /* {{{ */ { /* don't allow this to loop, ever ... */ switch (param->type) { - case STR_PARAM: { + case SHELL_PARAM: { FILE *fd = NULL; if ((fd=VCWD_POPEN((char*)param->str, "w"))) { /* do something perhaps ?? do we want input ?? */ From 0b19b9dd0c43484cc141106f2ac7265272c69162 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 08:40:33 +0000 Subject: [PATCH 052/137] fix #75 phpdbg disabled by default --- config.m4 | 2 +- config.w32 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config.m4 b/config.m4 index c48a5db60fc..dd6d425893a 100644 --- a/config.m4 +++ b/config.m4 @@ -3,7 +3,7 @@ dnl $Id$ dnl PHP_ARG_ENABLE(phpdbg, for phpdbg support, -[ --enable-phpdbg Build phpdbg], yes, yes) +[ --enable-phpdbg Build phpdbg], no, no) PHP_ARG_ENABLE(phpdbg-debug, for phpdbg debug build, [ --enable-phpdbg-debug Build phpdbg in debug mode], no, no) diff --git a/config.w32 b/config.w32 index 29031507b31..1ea862f59e4 100644 --- a/config.w32 +++ b/config.w32 @@ -1,4 +1,4 @@ -ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); +ARG_ENABLE('phpdbg', 'Build phpdbg', 'no'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c'; From 791828d00cf393f2fd0d1b49699b2b4dd13be339 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 08:47:15 +0000 Subject: [PATCH 053/137] fix zpp issues #74 --- phpdbg.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 01978b4c80c..7676687e712 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -216,7 +216,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ static PHP_FUNCTION(phpdbg_exec) { char *exec = NULL; - zend_ulong exec_len = 0L; + int exec_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) { return; @@ -258,9 +258,9 @@ static PHP_FUNCTION(phpdbg_exec) static PHP_FUNCTION(phpdbg_break) { if (ZEND_NUM_ARGS() > 0) { - long type; + long type = 0; char *expr = NULL; - zend_uint expr_len = 0; + int expr_len = 0; phpdbg_param_t param; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &type, &expr, &expr_len) == FAILURE) { @@ -318,9 +318,9 @@ static PHP_FUNCTION(phpdbg_clear) /* {{{ proto void phpdbg_color(integer element, string color) */ static PHP_FUNCTION(phpdbg_color) { - long element; - char *color; - zend_uint color_len; + long element = 0L; + char *color = NULL; + int color_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &element, &color, &color_len) == FAILURE) { return; @@ -340,8 +340,8 @@ static PHP_FUNCTION(phpdbg_color) /* {{{ proto void phpdbg_prompt(string prompt) */ static PHP_FUNCTION(phpdbg_prompt) { - char *prompt; - zend_uint prompt_len; + char *prompt = NULL; + int prompt_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &prompt, &prompt_len) == FAILURE) { return; From 8da9b7e3a2e25ff8cd536200d515cf0d9c01906f Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 09:13:42 +0000 Subject: [PATCH 054/137] fix #70 --- phpdbg_print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_print.c b/phpdbg_print.c index 5e3129ad7fb..7e549a27793 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -87,7 +87,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC) phpdbg_error("\tFailed to decode opline %16p", opline); } opline++; - } while (++opcode < end); + } while (opcode++ < end); zend_hash_destroy(&vars); } } break; From e392e730ea7cd006a9933cb088179c9a6a46d246 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 19:48:33 +0000 Subject: [PATCH 055/137] execute new stack now --- dev/phpdbg_lexer.l | 2 +- dev/phpdbg_parser.y | 26 +--- phpdbg.h | 1 + phpdbg_bp.c | 5 +- phpdbg_cmd.c | 299 +------------------------------------------- phpdbg_cmd.h | 17 +-- phpdbg_help.c | 6 +- phpdbg_lexer.c | 238 ++++++++++++++++++----------------- phpdbg_parser.c | 81 +++++------- phpdbg_parser.h | 2 +- phpdbg_prompt.c | 104 ++++++++++----- phpdbg_set.c | 20 +-- 12 files changed, 254 insertions(+), 547 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index bf74cbdc681..46137d66768 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -34,7 +34,7 @@ C_SHELL ?i:"shell" C_IF ?i:"if" DIGITS [0-9]+ -ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-]* +ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-\./]* NSID [\\\\]?{ID} METHOD {NSID}+::{ID} NUMERIC_METHOD {METHOD}[#]{DIGITS} diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 24bcc685372..49925f67098 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -111,7 +111,7 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { next->top = stack->top; stack->top = next; } - phpdbg_debug_param(next, "push ->"); + stack->len++; } @@ -146,16 +146,10 @@ phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_ if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { command = phpdbg_stack_resolve(matched[0]->subs, top, why); if (command) { - phpdbg_notice( - "Command matching with sub command %s %s", - matched[0]->name, command->name); return command; } } - phpdbg_notice( - "Command matching with %s", - matched[0]->name); return matched[0]; } break; @@ -191,29 +185,17 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (command->type) { case EVAL_PARAM: - PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); - break; + return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); case SHELL_PARAM: - PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); - break; + return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); case STR_PARAM: { - /* do resolve command(s) */ handler = phpdbg_stack_resolve( phpdbg_prompt_commands, &command, why); if (handler) { - /* get top of stack */ - params = command; - - /* prepare params */ - while (params) { - phpdbg_debug_param(params, "-> ..."); - params = params->next; - } - - return SUCCESS; + return handler->handler(command, NULL TSRMLS_CC); } else { return FAILURE; } diff --git a/phpdbg.h b/phpdbg.h index 68c505ca636..414500cab72 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -159,6 +159,7 @@ #define PHPDBG_STDERR 2 #define PHPDBG_IO_FDS 3 /* }}} */ + /* {{{ structs */ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 609644548fa..acb53450cb2 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -762,6 +762,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) /* {{{ */ { + /* if (input->argc > 3 && phpdbg_argv_is(2, "if")) { phpdbg_breakcond_t new_break; phpdbg_param_t new_param; @@ -776,7 +777,6 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpd expr_hash = zend_inline_hash_func(expr, expr_len); { - /* get a clean parameter from input string */ size_t sparam_len = 0L; char *sparam = input->string; @@ -791,7 +791,7 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpd &new_param TSRMLS_CC); goto usage; - default: { /* do nothing */ } break; + default: { } break; } expr_hash += phpdbg_hash_param(&new_param TSRMLS_CC); @@ -810,6 +810,7 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpd usage: phpdbg_error("usage: break at if "); } + */ } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 526d1183a57..dde0c813fa8 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -22,12 +22,6 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" -#include "phpdbg_parser.h" -#include "phpdbg_lexer.h" - -int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); -void phpdbg_stack_free(phpdbg_param_t *stack); -int yyparse(phpdbg_param_t *stack, yyscan_t scanner); ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -382,106 +376,13 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa return 0; } /* }}} */ -PHPDBG_API phpdbg_input_t **phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC) /* {{{ */ +PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { - char *p; - char b[PHPDBG_MAX_CMD]; - int l=0; - enum states { - IN_BETWEEN, - IN_WORD, - IN_STRING - } state = IN_BETWEEN; - phpdbg_input_t **argv = NULL; - - argv = (phpdbg_input_t**) emalloc(sizeof(phpdbg_input_t*)); - (*argc) = 0; - -#define RESET_STATE() do { \ - phpdbg_input_t *arg = emalloc(sizeof(phpdbg_input_t)); \ - if (arg) { \ - b[l]=0; \ - arg->length = l; \ - arg->string = estrndup(b, arg->length); \ - arg->argv = NULL; \ - arg->argc = 0; \ - argv = (phpdbg_input_t**) erealloc(argv, sizeof(phpdbg_input_t*) * ((*argc)+1)); \ - argv[(*argc)++] = arg; \ - l = 0; \ - } \ - state = IN_BETWEEN; \ -} while (0) - - for (p = buffer; *p != '\0'; p++) { - int c = (unsigned char) *p; - switch (state) { - case IN_BETWEEN: - if (isspace(c)) { - continue; - } - if (c == '"') { - state = IN_STRING; - continue; - } - state = IN_WORD; - b[l++]=c; - continue; - - case IN_STRING: - if (c == '"') { - if (buffer[(p - buffer)-1] == '\\') { - b[l-1]=c; - continue; - } - RESET_STATE(); - } else { - b[l++]=c; - } - continue; - - case IN_WORD: - if (isspace(c)) { - RESET_STATE(); - } else { - b[l++]=c; - } - continue; - } - } - - switch (state) { - case IN_WORD: { - RESET_STATE(); - } break; - - case IN_STRING: - phpdbg_error( - "Malformed command line (unclosed quote) @ %ld: %s!", - (p - buffer)-1, &buffer[(p - buffer)-1]); - break; - - case IN_BETWEEN: - break; - } - - if ((*argc) == 0) { - /* not needed */ - efree(argv); - - /* to be sure */ - return NULL; - } - - return argv; -} /* }}} */ - -PHPDBG_API phpdbg_input_t *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ -{ - phpdbg_input_t *buffer = NULL; char *cmd = NULL; #ifndef HAVE_LIBREADLINE char buf[PHPDBG_MAX_CMD]; #endif + char *buffer = NULL; if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && @@ -533,65 +434,8 @@ readline: } #endif } else cmd = buffered; - - /* allocate and sanitize buffer */ - buffer = (phpdbg_input_t*) ecalloc(1, sizeof(phpdbg_input_t)); - if (!buffer) { - return NULL; - } - - buffer->string = phpdbg_trim(cmd, strlen(cmd), &buffer->length); - - /* store constant pointer to start of buffer */ - buffer->start = (char* const*) buffer->string; - - buffer->argv = phpdbg_read_argv( - buffer->string, &buffer->argc TSRMLS_CC); - - { - yyscan_t scanner; - YY_BUFFER_STATE state; - phpdbg_param_t stack; - phpdbg_init_param(&stack, STACK_PARAM); - - if (yylex_init(&scanner)) { - phpdbg_error("could not initialize scanner"); - return buffer; - } - - state = yy_scan_string(buffer->string, scanner); - - if (yyparse(&stack, scanner) <= 0) { - char *why = NULL; - - if (phpdbg_stack_execute(&stack, &why) != SUCCESS) { - phpdbg_error( - "Execution Error: %s", - why ? why : "for no particular reason"); - } - - if (why) { - free(why); - } - } - yy_delete_buffer(state, scanner); - yylex_destroy(scanner); - - phpdbg_stack_free(&stack); - } - -#ifdef PHPDBG_DEBUG - if (buffer->argc) { - int arg = 0; - - while (arg < buffer->argc) { - phpdbg_debug( - "argv %d=%s", arg, buffer->argv[arg]->string); - arg++; - } - } -#endif + buffer = estrdup(cmd); #ifdef HAVE_LIBREADLINE if (!buffered && cmd && @@ -599,144 +443,13 @@ readline: free(cmd); } #endif - - return buffer; } - return NULL; + return buffer; } /* }}} */ -PHPDBG_API void phpdbg_destroy_argv(phpdbg_input_t **argv, int argc TSRMLS_DC) /* {{{ */ +PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */ { - if (argv) { - if (argc) { - int arg; - for (arg=0; argstring) { - efree((*input)->string); - } - - phpdbg_destroy_argv( - (*input)->argv, (*input)->argc TSRMLS_CC); - - efree(*input); - } -} /* }}} */ - -PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_input_t *input TSRMLS_DC) /* {{{ */ -{ - int rc = FAILURE; - - if (input->argc > 0) { - while (command && command->name && command->handler) { - if (((command->name_len == input->argv[0]->length) && - (memcmp(command->name, input->argv[0]->string, command->name_len) == SUCCESS)) || - (command->alias && - (input->argv[0]->length == 1) && - (command->alias == *input->argv[0]->string))) { - - phpdbg_param_t param; - phpdbg_command_t *initial_last_cmd; - phpdbg_param_t initial_last_param; - - param.type = EMPTY_PARAM; - - if (input->argc > 1) { - if (command->subs) { - phpdbg_input_t sub = *input; - - sub.string += input->argv[0]->length; - sub.length -= input->argv[0]->length; - - sub.string = phpdbg_trim( - sub.string, sub.length, &sub.length); - - sub.argc--; - sub.argv++; - - phpdbg_debug( - "trying sub commands in \"%s\" for \"%s\" with %d arguments", - command->name, sub.argv[0]->string, sub.argc-1); - - if (phpdbg_do_cmd(command->subs, &sub TSRMLS_CC) == SUCCESS) { - efree(sub.string); - return SUCCESS; - } - - efree(sub.string); - } - - /* no sub command found */ - { - char *store = input->string; - - input->string += input->argv[0]->length; - input->length -= input->argv[0]->length; - - input->string = phpdbg_trim( - input->string, input->length, &input->length); - - efree(store); - } - - /* pass parameter on */ - phpdbg_parse_param( - input->string, - input->length, - ¶m TSRMLS_CC); - } - - phpdbg_debug( - "found command %s for %s with %d arguments", - command->name, input->argv[0]->string, input->argc-1); - { - int arg; - for (arg=1; argargc; arg++) { - phpdbg_debug( - "\t#%d: [%s=%zu]", - arg, - input->argv[arg]->string, - input->argv[arg]->length); - } - } - - initial_last_param = PHPDBG_G(lparam); - initial_last_cmd = (phpdbg_command_t *)PHPDBG_G(lcmd); - PHPDBG_G(lparam) = param; - PHPDBG_G(lcmd) = (phpdbg_command_t *)command; - - rc = command->handler(¶m, input TSRMLS_CC); - - /* only set last command when it is worth it! */ - if (rc != FAILURE && !(PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) { - phpdbg_clear_param(&initial_last_param TSRMLS_CC); - } else if (PHPDBG_G(lcmd) == command && !memcmp(&PHPDBG_G(lparam),& initial_last_param, sizeof(phpdbg_param_t))) { - PHPDBG_G(lparam) = initial_last_param; - PHPDBG_G(lcmd) = initial_last_cmd; - phpdbg_clear_param(¶m TSRMLS_CC); - } - break; - } - command++; - } - } else { - /* this should NEVER happen */ - phpdbg_error( - "No function executed!!"); - } - - return rc; + efree(*input); } /* }}} */ diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index cf503812a72..af24837d946 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -140,16 +140,8 @@ typedef struct { /* * Input Management */ -PHPDBG_API phpdbg_input_t* phpdbg_read_input(char *buffered TSRMLS_DC); -PHPDBG_API void phpdbg_destroy_input(phpdbg_input_t** TSRMLS_DC); - -/* -* Argument Management -*/ -PHPDBG_API phpdbg_input_t** phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC); -PHPDBG_API void phpdbg_destroy_argv(phpdbg_input_t **argv, int argc TSRMLS_DC); -#define phpdbg_argv_is(n, s) \ - (memcmp(input->argv[n]->string, s, input->argv[n]->length) == SUCCESS) +PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC); +PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); /* * Parameter Management @@ -162,11 +154,6 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t * TSRMLS_DC); PHPDBG_API const char* phpdbg_get_param_type(const phpdbg_param_t* TSRMLS_DC); PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer TSRMLS_DC); -/* -* Command Executor -*/ -PHPDBG_API int phpdbg_do_cmd(const phpdbg_command_t*, phpdbg_input_t* TSRMLS_DC); - /** * Command Declarators */ diff --git a/phpdbg_help.c b/phpdbg_help.c index 3aa82848e00..8dcc89007d0 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -208,13 +208,13 @@ PHPDBG_COMMAND(help) /* {{{ */ phpdbg_command_t const *cmd; int n; - if (param->type == EMPTY_PARAM) { + if (!param || param->type == EMPTY_PARAM) { pretty_print(get_help("overview!" TSRMLS_CC) TSRMLS_CC); return SUCCESS; } - if (param->type == STR_PARAM) { - n = get_command( param->str, param->len, &cmd, phpdbg_prompt_commands TSRMLS_CC); + if (param && param->type == STR_PARAM) { + n = get_command(param->str, param->len, &cmd, phpdbg_prompt_commands TSRMLS_CC); if (n==1) { summary_print(cmd TSRMLS_CC); diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index e9e243c5e55..9999a639786 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -379,16 +379,16 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 7, 1, 1, 8, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 10, 1, 1, - 1, 1, 1, 1, 11, 12, 13, 14, 15, 16, - 7, 17, 18, 7, 7, 19, 7, 20, 21, 7, - 7, 22, 23, 24, 25, 26, 7, 7, 27, 7, - 1, 28, 1, 1, 7, 1, 29, 30, 13, 31, + 1, 1, 1, 1, 7, 8, 8, 9, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, 1, 1, + 1, 1, 1, 1, 12, 13, 14, 15, 16, 17, + 7, 18, 19, 7, 7, 20, 7, 21, 22, 7, + 7, 23, 24, 25, 26, 27, 7, 7, 28, 7, + 1, 29, 1, 1, 7, 1, 30, 31, 14, 32, - 32, 33, 7, 34, 35, 7, 7, 36, 7, 37, - 38, 7, 7, 39, 40, 41, 42, 43, 7, 44, - 45, 7, 1, 1, 1, 1, 7, 7, 7, 7, + 33, 34, 7, 35, 36, 7, 7, 37, 7, 38, + 39, 7, 7, 40, 41, 42, 43, 44, 7, 45, + 46, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, @@ -405,29 +405,29 @@ static yyconst flex_int32_t yy_ec[256] = 7, 7, 7, 7, 7 } ; -static yyconst flex_int32_t yy_meta[46] = +static yyconst flex_int32_t yy_meta[47] = { 0, - 1, 1, 2, 3, 1, 4, 5, 4, 4, 1, + 1, 1, 2, 3, 1, 4, 5, 4, 4, 4, + 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 1, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5 + 5, 5, 5, 5, 5, 5 } ; static yyconst flex_int16_t yy_base[107] = { 0, - 0, 0, 44, 47, 160, 136, 50, 53, 62, 57, - 85, 60, 63, 433, 113, 63, 91, 64, 89, 112, - 41, 90, 118, 153, 0, 75, 135, 101, 126, 162, - 140, 147, 112, 95, 162, 170, 168, 66, 150, 174, - 190, 178, 211, 171, 199, 218, 195, 197, 198, 219, - 220, 230, 221, 241, 231, 0, 199, 196, 433, 100, - 252, 199, 0, 281, 0, 240, 267, 259, 270, 232, - 280, 285, 278, 90, 320, 0, 289, 314, 296, 319, - 317, 309, 262, 86, 320, 325, 323, 324, 264, 346, - 348, 349, 347, 350, 433, 385, 390, 395, 400, 405, + 0, 0, 45, 48, 148, 133, 51, 54, 57, 59, + 88, 57, 62, 448, 117, 65, 94, 95, 113, 120, + 115, 64, 124, 160, 0, 72, 75, 105, 71, 170, + 173, 174, 116, 94, 177, 104, 181, 119, 123, 184, + 206, 187, 227, 164, 215, 234, 182, 128, 148, 213, + 185, 236, 237, 243, 212, 0, 220, 101, 448, 92, + 266, 272, 0, 295, 0, 280, 255, 289, 266, 214, + 292, 298, 258, 79, 334, 0, 302, 328, 294, 333, + 331, 322, 216, 76, 334, 340, 336, 338, 219, 359, + 362, 364, 361, 363, 448, 400, 405, 410, 415, 420, - 410, 415, 420, 69, 425, 427 + 425, 430, 435, 64, 440, 442 } ; static yyconst flex_int16_t yy_def[107] = @@ -446,116 +446,122 @@ static yyconst flex_int16_t yy_def[107] = 95, 95, 95, 95, 95, 95 } ; -static yyconst flex_int16_t yy_nxt[479] = +static yyconst flex_int16_t yy_nxt[495] = { 0, - 6, 7, 8, 9, 10, 6, 11, 12, 13, 14, - 11, 11, 11, 15, 16, 17, 11, 18, 11, 19, - 20, 11, 21, 22, 11, 11, 23, 24, 11, 11, - 15, 16, 17, 11, 18, 11, 19, 20, 11, 21, - 22, 11, 11, 11, 23, 26, 27, 26, 26, 27, - 26, 30, 30, 31, 30, 30, 31, 52, 38, 29, - 33, 34, 29, 31, 31, 31, 35, 42, 42, 29, - 42, 42, 29, 74, 52, 38, 57, 31, 57, 48, - 38, 38, 45, 38, 36, 28, 28, 28, 46, 28, - 37, 83, 39, 39, 40, 83, 48, 38, 38, 45, + 6, 7, 8, 9, 10, 6, 11, 6, 12, 13, + 14, 11, 11, 11, 15, 16, 17, 11, 18, 11, + 19, 20, 11, 21, 22, 11, 11, 23, 24, 11, + 11, 15, 16, 17, 11, 18, 11, 19, 20, 11, + 21, 22, 11, 11, 11, 23, 26, 27, 26, 26, + 27, 26, 30, 30, 31, 30, 30, 31, 31, 31, + 31, 29, 33, 34, 29, 42, 42, 29, 74, 35, + 42, 42, 29, 57, 31, 57, 31, 31, 31, 58, + 58, 83, 38, 38, 83, 45, 53, 36, 28, 28, + 28, 46, 28, 37, 95, 39, 39, 39, 40, 38, - 38, 47, 95, 43, 29, 46, 38, 38, 38, 49, - 29, 53, 41, 28, 28, 28, 59, 28, 37, 47, - 39, 39, 40, 38, 38, 38, 49, 50, 53, 38, - 44, 51, 54, 58, 58, 38, 31, 31, 31, 60, - 41, 31, 31, 31, 50, 29, 38, 44, 51, 54, - 33, 34, 38, 28, 28, 28, 35, 28, 28, 95, - 28, 28, 29, 30, 30, 31, 59, 38, 95, 61, - 61, 29, 28, 33, 36, 62, 62, 29, 95, 35, - 28, 58, 58, 63, 38, 42, 42, 29, 38, 60, - 28, 28, 28, 66, 28, 28, 95, 28, 28, 29, + 38, 43, 45, 53, 29, 47, 28, 33, 46, 58, + 58, 48, 38, 38, 35, 29, 41, 28, 28, 28, + 59, 28, 37, 47, 39, 39, 39, 40, 48, 38, + 38, 38, 52, 38, 49, 44, 50, 38, 38, 54, + 51, 38, 38, 29, 60, 41, 38, 95, 38, 52, + 38, 49, 44, 50, 38, 38, 54, 51, 38, 38, + 28, 28, 28, 38, 28, 28, 38, 28, 28, 28, + 29, 30, 30, 31, 31, 31, 31, 33, 34, 95, + 29, 59, 38, 38, 35, 61, 61, 66, 28, 62, + 62, 29, 58, 58, 63, 42, 42, 29, 95, 38, - 57, 31, 57, 58, 58, 38, 62, 62, 29, 67, - 66, 95, 38, 69, 38, 38, 38, 28, 65, 65, - 29, 65, 65, 65, 65, 65, 65, 67, 68, 38, - 69, 38, 38, 38, 70, 38, 38, 38, 38, 65, - 65, 65, 65, 65, 71, 72, 68, 38, 38, 38, - 77, 70, 38, 38, 38, 38, 59, 38, 38, 61, - 61, 71, 72, 73, 38, 38, 38, 95, 77, 89, - 89, 89, 89, 95, 38, 38, 38, 79, 78, 60, - 73, 28, 28, 28, 38, 28, 28, 38, 76, 76, - 40, 95, 80, 38, 79, 38, 78, 38, 81, 82, + 38, 69, 36, 38, 66, 60, 28, 28, 28, 95, + 28, 28, 95, 28, 28, 28, 29, 38, 69, 95, + 38, 57, 31, 57, 89, 89, 67, 89, 89, 70, + 38, 38, 38, 38, 28, 65, 65, 29, 65, 65, + 65, 65, 65, 65, 67, 68, 70, 38, 38, 38, + 38, 71, 38, 95, 38, 38, 65, 65, 65, 65, + 65, 38, 72, 68, 95, 95, 73, 78, 71, 38, + 59, 38, 38, 38, 61, 61, 38, 95, 38, 72, + 62, 62, 29, 73, 38, 78, 95, 95, 95, 80, + 38, 77, 95, 38, 60, 28, 28, 28, 38, 28, - 85, 38, 38, 95, 38, 95, 38, 95, 41, 80, - 95, 95, 38, 38, 38, 81, 82, 95, 85, 38, - 28, 28, 28, 38, 28, 28, 38, 76, 76, 40, - 38, 38, 86, 87, 38, 88, 38, 38, 90, 91, - 38, 38, 38, 38, 95, 95, 95, 41, 38, 86, - 87, 38, 88, 38, 38, 90, 91, 38, 38, 38, - 92, 93, 94, 38, 38, 38, 38, 38, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 92, 93, 94, - 38, 38, 38, 38, 38, 25, 25, 25, 25, 25, - 28, 28, 95, 28, 28, 32, 32, 32, 32, 32, + 28, 38, 76, 76, 76, 40, 80, 38, 79, 77, + 38, 81, 38, 82, 85, 38, 38, 95, 95, 95, + 38, 95, 95, 41, 38, 79, 95, 38, 81, 38, + 82, 95, 85, 38, 28, 28, 28, 38, 28, 28, + 38, 76, 76, 76, 40, 95, 38, 86, 87, 38, + 88, 38, 38, 90, 38, 91, 38, 38, 38, 95, + 95, 95, 41, 38, 86, 87, 38, 88, 38, 38, + 90, 38, 91, 38, 92, 38, 93, 38, 94, 38, + 38, 38, 38, 95, 95, 95, 95, 95, 95, 95, + 95, 92, 95, 93, 38, 94, 38, 38, 38, 38, - 38, 38, 95, 38, 38, 55, 55, 95, 55, 55, - 56, 95, 56, 56, 56, 33, 33, 33, 33, 33, - 64, 64, 95, 64, 64, 75, 75, 95, 75, 75, - 84, 84, 5, 95, 95, 95, 95, 95, 95, 95, + 25, 25, 25, 25, 25, 28, 28, 95, 28, 28, + 32, 32, 32, 32, 32, 38, 38, 95, 38, 38, + 55, 55, 95, 55, 55, 56, 95, 56, 56, 56, + 33, 33, 33, 33, 33, 64, 64, 95, 64, 64, + 75, 75, 95, 75, 75, 84, 84, 5, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95 + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95 + } ; -static yyconst flex_int16_t yy_chk[479] = +static yyconst flex_int16_t yy_chk[495] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 3, 3, 4, 4, - 4, 7, 7, 7, 8, 8, 8, 21, 21, 7, - 10, 10, 8, 9, 9, 9, 10, 12, 12, 12, - 13, 13, 13, 104, 21, 21, 26, 26, 26, 18, - 16, 18, 16, 38, 10, 11, 11, 11, 16, 11, - 11, 84, 11, 11, 11, 74, 18, 16, 18, 16, + 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, + 4, 4, 7, 7, 7, 8, 8, 8, 9, 9, + 9, 7, 10, 10, 8, 12, 12, 12, 104, 10, + 13, 13, 13, 26, 26, 26, 27, 27, 27, 29, + 29, 84, 22, 16, 74, 16, 22, 10, 11, 11, + 11, 16, 11, 11, 60, 11, 11, 11, 11, 22, - 38, 17, 60, 12, 34, 16, 19, 22, 17, 19, - 28, 22, 11, 15, 15, 15, 33, 15, 15, 17, - 15, 15, 15, 19, 22, 17, 19, 20, 22, 20, - 15, 20, 23, 29, 29, 23, 27, 27, 27, 33, - 15, 31, 31, 31, 20, 6, 20, 15, 20, 23, - 32, 32, 23, 24, 24, 24, 32, 24, 24, 5, - 24, 24, 24, 30, 30, 30, 35, 39, 0, 35, - 35, 30, 36, 36, 32, 37, 37, 37, 0, 36, - 24, 40, 40, 40, 39, 42, 42, 42, 44, 35, - 41, 41, 41, 44, 41, 41, 0, 41, 41, 41, + 16, 12, 16, 22, 34, 17, 36, 36, 16, 58, + 58, 18, 17, 18, 36, 28, 11, 15, 15, 15, + 33, 15, 15, 17, 15, 15, 15, 15, 18, 17, + 18, 19, 21, 21, 19, 15, 20, 38, 20, 23, + 20, 39, 23, 6, 33, 15, 48, 5, 19, 21, + 21, 19, 15, 20, 38, 20, 23, 20, 39, 23, + 24, 24, 24, 48, 24, 24, 49, 24, 24, 24, + 24, 30, 30, 30, 31, 31, 31, 32, 32, 0, + 30, 35, 44, 49, 32, 35, 35, 44, 24, 37, + 37, 37, 40, 40, 40, 42, 42, 42, 0, 44, - 57, 57, 57, 58, 58, 44, 62, 62, 62, 45, - 44, 0, 47, 47, 48, 49, 45, 41, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 45, 46, 47, - 47, 48, 49, 45, 50, 46, 50, 51, 53, 43, - 43, 43, 43, 43, 52, 53, 46, 52, 55, 70, - 66, 50, 46, 50, 51, 53, 61, 66, 54, 61, - 61, 52, 53, 54, 52, 55, 70, 0, 66, 83, - 83, 89, 89, 0, 66, 54, 68, 68, 67, 61, - 54, 64, 64, 64, 67, 64, 64, 69, 64, 64, - 64, 0, 69, 68, 68, 73, 67, 71, 71, 72, + 47, 47, 32, 51, 44, 35, 41, 41, 41, 0, + 41, 41, 0, 41, 41, 41, 41, 47, 47, 0, + 51, 57, 57, 57, 83, 83, 45, 89, 89, 50, + 55, 50, 70, 45, 41, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 45, 46, 50, 55, 50, 70, + 45, 52, 46, 0, 52, 53, 43, 43, 43, 43, + 43, 54, 53, 46, 0, 0, 54, 67, 52, 46, + 61, 52, 53, 67, 61, 61, 73, 0, 54, 53, + 62, 62, 62, 54, 69, 67, 0, 0, 0, 69, + 67, 66, 0, 73, 61, 64, 64, 64, 66, 64, - 77, 67, 72, 0, 69, 0, 77, 0, 64, 69, - 0, 0, 73, 79, 71, 71, 72, 0, 77, 72, - 75, 75, 75, 77, 75, 75, 82, 75, 75, 75, - 79, 78, 78, 80, 81, 81, 80, 85, 85, 86, - 87, 88, 86, 82, 0, 0, 0, 75, 78, 78, - 80, 81, 81, 80, 85, 85, 86, 87, 88, 86, - 90, 91, 92, 90, 93, 91, 92, 94, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 90, 91, 92, - 90, 93, 91, 92, 94, 96, 96, 96, 96, 96, - 97, 97, 0, 97, 97, 98, 98, 98, 98, 98, + 64, 69, 64, 64, 64, 64, 69, 68, 68, 66, + 71, 71, 79, 72, 77, 66, 72, 0, 0, 0, + 77, 0, 0, 64, 68, 68, 0, 71, 71, 79, + 72, 0, 77, 72, 75, 75, 75, 77, 75, 75, + 82, 75, 75, 75, 75, 0, 78, 78, 80, 81, + 81, 80, 85, 85, 87, 86, 88, 82, 86, 0, + 0, 0, 75, 78, 78, 80, 81, 81, 80, 85, + 85, 87, 86, 88, 90, 86, 91, 90, 92, 93, + 91, 94, 92, 0, 0, 0, 0, 0, 0, 0, + 0, 90, 0, 91, 90, 92, 93, 91, 94, 92, - 99, 99, 0, 99, 99, 100, 100, 0, 100, 100, - 101, 0, 101, 101, 101, 102, 102, 102, 102, 102, - 103, 103, 0, 103, 103, 105, 105, 0, 105, 105, - 106, 106, 95, 95, 95, 95, 95, 95, 95, 95, + 96, 96, 96, 96, 96, 97, 97, 0, 97, 97, + 98, 98, 98, 98, 98, 99, 99, 0, 99, 99, + 100, 100, 0, 100, 100, 101, 0, 101, 101, 101, + 102, 102, 102, 102, 102, 103, 103, 0, 103, 103, + 105, 105, 0, 105, 105, 106, 106, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95 + 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95 + } ; /* The intent behind this definition is that it'll catch @@ -581,7 +587,7 @@ static yyconst flex_int16_t yy_chk[479] = #include #define YY_NO_UNISTD_H 1 -#line 585 "sapi/phpdbg/phpdbg_lexer.c" +#line 591 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -821,7 +827,7 @@ YY_DECL #line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 825 "sapi/phpdbg/phpdbg_lexer.c" +#line 831 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -1060,7 +1066,7 @@ YY_RULE_SETUP #line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1064 "sapi/phpdbg/phpdbg_lexer.c" +#line 1070 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 79745cef8be..ffc8de0b4a1 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -179,7 +179,7 @@ static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { next->top = stack->top; stack->top = next; } - phpdbg_debug_param(next, "push ->"); + stack->len++; } @@ -214,16 +214,10 @@ phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_ if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { command = phpdbg_stack_resolve(matched[0]->subs, top, why); if (command) { - phpdbg_notice( - "Command matching with sub command %s %s", - matched[0]->name, command->name); return command; } } - phpdbg_notice( - "Command matching with %s", - matched[0]->name); return matched[0]; } break; @@ -259,29 +253,17 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (command->type) { case EVAL_PARAM: - PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); - break; + return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); case SHELL_PARAM: - PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); - break; + return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); case STR_PARAM: { - /* do resolve command(s) */ handler = phpdbg_stack_resolve( phpdbg_prompt_commands, &command, why); if (handler) { - /* get top of stack */ - params = command; - - /* prepare params */ - while (params) { - phpdbg_debug_param(params, "-> ..."); - params = params->next; - } - - return SUCCESS; + return handler->handler(command, NULL TSRMLS_CC); } else { return FAILURE; } @@ -298,9 +280,8 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { - /* Line 268 of yacc.c */ -#line 304 "sapi/phpdbg/phpdbg_parser.c" +#line 285 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -323,7 +304,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 234 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -334,7 +315,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 338 "sapi/phpdbg/phpdbg_parser.c" +#line 319 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -375,7 +356,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 379 "sapi/phpdbg/phpdbg_parser.c" +#line 360 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -669,9 +650,9 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 270, 270, 274, 275, 279, 280, 284, 285, 289, - 290, 294, 295, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 313 + 0, 251, 251, 255, 256, 260, 261, 265, 266, 270, + 271, 275, 276, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 294 }; #endif @@ -1629,133 +1610,133 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 274 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 255 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 275 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 256 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 284 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 265 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 285 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 266 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 289 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 270 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } break; case 10: /* Line 1806 of yacc.c */ -#line 290 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 271 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } break; case 12: /* Line 1806 of yacc.c */ -#line 295 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 276 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 299 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 280 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 300 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 281 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 301 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 282 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 302 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 283 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 303 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 284 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 304 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 285 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 305 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 286 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 306 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 287 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: /* Line 1806 of yacc.c */ -#line 307 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 288 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 22: /* Line 1806 of yacc.c */ -#line 308 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 289 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: /* Line 1806 of yacc.c */ -#line 309 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 290 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } break; /* Line 1806 of yacc.c */ -#line 1759 "sapi/phpdbg/phpdbg_parser.c" +#line 1740 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1986,6 +1967,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 315 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 296 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 612982c46fa..b307843dec1 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 234 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 632ceb97611..9a0946138c4 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -35,6 +35,12 @@ #include "phpdbg_cmd.h" #include "phpdbg_set.h" #include "phpdbg_frame.h" +#include "phpdbg_lexer.h" +#include "phpdbg_parser.h" + +int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); +void phpdbg_stack_free(phpdbg_param_t *stack); +int yyparse(phpdbg_param_t *stack, yyscan_t scanner); /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { @@ -188,8 +194,8 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ goto next_line; } - { - phpdbg_input_t *input = phpdbg_read_input(cmd TSRMLS_CC); + /*{ + phpdbg_param_t *input = phpdbg_read_input(cmd TSRMLS_CC); switch (phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { @@ -200,7 +206,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ break; } phpdbg_destroy_input(&input TSRMLS_CC); - } + }*/ } next_line: @@ -798,6 +804,7 @@ PHPDBG_COMMAND(shell) /* {{{ */ PHPDBG_COMMAND(source) /* {{{ */ { + /* switch (param->type) { case STR_PARAM: { if (input->argc > 2) { @@ -820,7 +827,7 @@ PHPDBG_COMMAND(source) /* {{{ */ } break; phpdbg_default_switch_case(); - } + }*/ return SUCCESS; } /* }}} */ @@ -860,9 +867,6 @@ PHPDBG_COMMAND(quit) /* {{{ */ { /* don't allow this to loop, ever ... */ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - - phpdbg_destroy_input((phpdbg_input_t**)&input TSRMLS_CC); - PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; zend_bailout(); } @@ -928,9 +932,10 @@ PHPDBG_COMMAND(quiet) /* {{{ */ PHPDBG_COMMAND(list) /* {{{ */ { - switch (param->type) { + if (!param || param->type == EMPTY_PARAM) { + return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); + } else switch (param->type) { case NUMERIC_PARAM: - case EMPTY_PARAM: return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); case FILE_PARAM: @@ -952,38 +957,65 @@ PHPDBG_COMMAND(list) /* {{{ */ int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; - phpdbg_input_t *input; - + char *why = NULL; + char *input = NULL; + phpdbg_param_t stack; + PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; input = phpdbg_read_input(NULL TSRMLS_CC); - - if (input && input->length > 0L) { + + printf("got input %s\n", input); + + if (input) { do { - switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { - case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { - phpdbg_error("Failed to execute %s!", input->string); - } - } - break; + yyscan_t scanner; + YY_BUFFER_STATE state; - case PHPDBG_LEAVE: - case PHPDBG_FINISH: - case PHPDBG_UNTIL: - case PHPDBG_NEXT: { - if (!EG(in_execution)) { - phpdbg_error("Not running"); - } - goto out; - } + phpdbg_init_param(&stack, STACK_PARAM); + + if (yylex_init(&scanner)) { + phpdbg_error( + "could not initialize scanner"); + return FAILURE; } - phpdbg_destroy_input(&input TSRMLS_CC); - } while ((input = phpdbg_read_input(NULL TSRMLS_CC)) && (input->length > 0L)); + state = yy_scan_string(input, scanner); + + if (yyparse(&stack, scanner) <= 0) { + switch (ret = phpdbg_stack_execute(&stack, &why)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + /*if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { + + }*/ + phpdbg_error("%s", why); + } + if (why) + free(why); + break; - if (input && !input->length) + case PHPDBG_LEAVE: + case PHPDBG_FINISH: + case PHPDBG_UNTIL: + case PHPDBG_NEXT: { + if (!EG(in_execution)) { + phpdbg_error("Not running"); + } + goto out; + } + } + } + + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); + + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); + + } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); + + if (!input) goto last; } else { @@ -996,7 +1028,11 @@ last: } out: - phpdbg_destroy_input(&input TSRMLS_CC); + if (input) { + phpdbg_destroy_input(&input TSRMLS_CC); + } + + phpdbg_stack_free(&stack); if (EG(in_execution)) { phpdbg_restore_frame(TSRMLS_C); diff --git a/phpdbg_set.c b/phpdbg_set.c index 50c07b66d85..6280086da49 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -56,12 +56,10 @@ PHPDBG_SET(prompt) /* {{{ */ PHPDBG_SET(break) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: - phpdbg_writeln("%s", - PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); - break; - + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", + PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); + } else switch (param->type) { case STR_PARAM: if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { phpdbg_enable_breakpoints(TSRMLS_C); @@ -71,12 +69,14 @@ PHPDBG_SET(break) /* {{{ */ break; case NUMERIC_PARAM: { - if (input->argc > 2) { + if (input && input->argc > 2) { + /* if (phpdbg_argv_is(2, "on")) { phpdbg_enable_breakpoint(param->num TSRMLS_CC); } else if (phpdbg_argv_is(2, "off")) { phpdbg_disable_breakpoint(param->num TSRMLS_CC); } + */ } else { phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); if (brake) { @@ -106,7 +106,7 @@ PHPDBG_SET(color) /* {{{ */ /* @TODO(anyone) make this consistent with other set commands */ if (color) { - if (phpdbg_argv_is(1, "prompt")) { + /*if (phpdbg_argv_is(1, "prompt")) { phpdbg_notice( "setting prompt color to %s (%s)", color->name, color->code); element = PHPDBG_COLOR_PROMPT; @@ -125,9 +125,9 @@ PHPDBG_SET(color) /* {{{ */ element = PHPDBG_COLOR_NOTICE; } else goto usage; - +*/ /* set color for element */ - phpdbg_set_color(element, color TSRMLS_CC); + /* phpdbg_set_color(element, color TSRMLS_CC); */ } else { phpdbg_error( "Failed to find the requested color (%s)", input->argv[2]->string); From 1952750af600c759648d32a3b9badcb61f542f14 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Tue, 18 Feb 2014 20:04:02 +0000 Subject: [PATCH 056/137] ... --- dev/phpdbg_parser.y | 198 ++-------------------------------- phpdbg_cmd.c | 192 +++++++++++++++++++++++++++++++++ phpdbg_cmd.h | 9 ++ phpdbg_parser.c | 254 +++++++------------------------------------- phpdbg_parser.h | 2 +- phpdbg_prompt.c | 2 - 6 files changed, 252 insertions(+), 405 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 49925f67098..90e79f8b5a3 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -11,6 +11,7 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_cmd.h" #include "phpdbg_prompt.h" #define YYSTYPE phpdbg_param_t @@ -22,194 +23,17 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { phpdbg_error("Parse Error: %s", msg); + { + const phpdbg_param_t *top = stack; + zend_ulong position = 0L; + + while (top) { + phpdbg_param_debug( + top, "--> "); + top = top->next; + } + } } - -void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { - if (param && param->type) { - switch (param->type) { - case STR_PARAM: - fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); - break; - - case ADDR_PARAM: - fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); - break; - - case FILE_PARAM: - fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); - break; - - case METHOD_PARAM: - fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); - break; - - case NUMERIC_METHOD_PARAM: - fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); - break; - - case NUMERIC_FUNCTION_PARAM: - fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); - break; - - case NUMERIC_PARAM: - fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); - break; - - case COND_PARAM: - fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); - break; - } - } -} - -void phpdbg_stack_free(phpdbg_param_t *stack) { - if (stack && stack->next) { - phpdbg_param_t *remove = stack->next; - - while (remove) { - phpdbg_param_t *next = NULL; - - if (remove->next) - next = remove->next; - - switch (remove->type) { - case STR_PARAM: - if (remove->str) { - free(remove->str); - } - break; - - case FILE_PARAM: - if (remove->file.name) { - free(remove->file.name); - } - break; - } - - free(remove); - - if (next) - remove = next; - else break; - } - } -} - -static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { - phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); - - if (!next) - return; - - *(next) = *(param); - - if (stack->top == NULL) { - stack->top = next; - stack->next = next; - } else { - stack->top->next = next; - next->top = stack->top; - stack->top = next; - } - - stack->len++; -} - -phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { - const phpdbg_command_t *command = commands; - phpdbg_param_t *name = *top; - phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; - ulong matches = 0L; - - while (command && command->name && command->handler) { - if (command->name_len >= name->len) { - if (memcmp(command->name, name->str, name->len) == SUCCESS) { - if (matches < 3) { - matched[matches] = command; - matches++; - } else break; - } - } - command++; - } - - switch (matches) { - case 0: { - asprintf( - why, - "The command %s could not be found", - name->str); - } break; - - case 1: { - (*top) = (*top)->next; - if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { - command = phpdbg_stack_resolve(matched[0]->subs, top, why); - if (command) { - return command; - } - } - - return matched[0]; - } break; - - default: { - asprintf( - why, - "The command %s is ambigious, matching %d commands", - name->str, matches); - } - } - - return NULL; -} - -int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { - phpdbg_param_t *command = NULL, - *params = NULL; - phpdbg_command_t *handler = NULL; - - if (stack->type != STACK_PARAM) { - asprintf( - why, "the passed argument was not a stack !!"); - return FAILURE; - } - - if (!stack->len) { - asprintf( - why, "the stack contains nothing !!"); - return FAILURE; - } - - command = (phpdbg_param_t*) stack->next; - - switch (command->type) { - case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); - - case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); - - case STR_PARAM: { - handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, &command, why); - - if (handler) { - return handler->handler(command, NULL TSRMLS_CC); - } else { - return FAILURE; - } - } break; - - default: - asprintf( - why, "the first parameter makes no sense !!"); - return FAILURE; - } - - return SUCCESS; -} - %} %code requires { diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index dde0c813fa8..27b8e15de89 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -22,6 +22,7 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" #include "phpdbg_set.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -376,6 +377,197 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa return 0; } /* }}} */ +/* {{{ */ +PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) { + if (param && param->type) { + switch (param->type) { + case STR_PARAM: + fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); + break; + + case ADDR_PARAM: + fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); + break; + + case FILE_PARAM: + fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); + break; + + case METHOD_PARAM: + fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_METHOD_PARAM: + fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); + break; + + case NUMERIC_PARAM: + fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); + break; + + case COND_PARAM: + fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); + break; + } + } +} /* }}} */ + +/* {{{ */ +PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { + if (stack && stack->next) { + phpdbg_param_t *remove = stack->next; + + while (remove) { + phpdbg_param_t *next = NULL; + + if (remove->next) + next = remove->next; + + switch (remove->type) { + case STR_PARAM: + if (remove->str) { + free(remove->str); + } + break; + + case FILE_PARAM: + if (remove->file.name) { + free(remove->file.name); + } + break; + } + + free(remove); + + if (next) + remove = next; + else break; + } + } +} /* }}} */ + +/* {{{ */ +PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { + phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); + + if (!next) + return; + + *(next) = *(param); + + if (stack->top == NULL) { + stack->top = next; + stack->next = next; + } else { + stack->top->next = next; + next->top = stack->top; + stack->top = next; + } + + stack->len++; +} /* }}} */ + +/* {{{ */ +PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { + const phpdbg_command_t *command = commands; + phpdbg_param_t *name = *top; + phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; + ulong matches = 0L; + + while (command && command->name && command->handler) { + if (command->name_len >= name->len) { + if (memcmp(command->name, name->str, name->len) == SUCCESS) { + if (matches < 3) { + matched[matches] = command; + matches++; + } else break; + } + } + command++; + } + + switch (matches) { + case 0: { + asprintf( + why, + "The command %s could not be found", + name->str); + } break; + + case 1: { + (*top) = (*top)->next; + if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { + command = phpdbg_stack_resolve(matched[0]->subs, top, why); + if (command) { + return command; + } + } + + return matched[0]; + } break; + + default: { + asprintf( + why, + "The command %s is ambigious, matching %d commands", + name->str, matches); + } + } + + return NULL; +} /* }}} */ + +/* {{{ */ +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { + phpdbg_param_t *command = NULL, + *params = NULL; + phpdbg_command_t *handler = NULL; + + if (stack->type != STACK_PARAM) { + asprintf( + why, "the passed argument was not a stack !!"); + return FAILURE; + } + + if (!stack->len) { + asprintf( + why, "the stack contains nothing !!"); + return FAILURE; + } + + command = (phpdbg_param_t*) stack->next; + + switch (command->type) { + case EVAL_PARAM: + return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); + + case SHELL_PARAM: + return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); + + case STR_PARAM: { + handler = phpdbg_stack_resolve( + phpdbg_prompt_commands, &command, why); + + if (handler) { + return handler->handler(command, NULL TSRMLS_CC); + } else { + return FAILURE; + } + } break; + + default: + asprintf( + why, "the first parameter makes no sense !!"); + return FAILURE; + } + + return SUCCESS; +} /* }}} */ + PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { char *cmd = NULL; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index af24837d946..d22650c6716 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -143,6 +143,14 @@ typedef struct { PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC); PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); +/** + * Stack Management + */ +PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); +PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why); +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); +PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); + /* * Parameter Management */ @@ -153,6 +161,7 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *, const phpdbg_par PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t * TSRMLS_DC); PHPDBG_API const char* phpdbg_get_param_type(const phpdbg_param_t* TSRMLS_DC); PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **pointer TSRMLS_DC); +PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg); /** * Command Declarators diff --git a/phpdbg_parser.c b/phpdbg_parser.c index ffc8de0b4a1..37bd4d80bc3 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -79,6 +79,7 @@ #include "phpdbg.h" #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_cmd.h" #include "phpdbg_prompt.h" #define YYSTYPE phpdbg_param_t @@ -90,198 +91,21 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { phpdbg_error("Parse Error: %s", msg); + { + const phpdbg_param_t *top = stack; + zend_ulong position = 0L; + + while (top) { + phpdbg_param_debug( + top, "--> "); + top = top->next; + } + } } -void phpdbg_debug_param(const phpdbg_param_t *param, const char *msg) { - if (param && param->type) { - switch (param->type) { - case STR_PARAM: - fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); - break; - - case ADDR_PARAM: - fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); - break; - - case FILE_PARAM: - fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); - break; - - case METHOD_PARAM: - fprintf(stderr, "%s METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); - break; - - case NUMERIC_METHOD_PARAM: - fprintf(stderr, "%s NUMERIC_METHOD_PARAM(%s::%s)\n", msg, param->method.class, param->method.name); - break; - - case NUMERIC_FUNCTION_PARAM: - fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); - break; - - case NUMERIC_PARAM: - fprintf(stderr, "%s NUMERIC_PARAM(%ld)\n", msg, param->num); - break; - - case COND_PARAM: - fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); - break; - } - } -} - -void phpdbg_stack_free(phpdbg_param_t *stack) { - if (stack && stack->next) { - phpdbg_param_t *remove = stack->next; - - while (remove) { - phpdbg_param_t *next = NULL; - - if (remove->next) - next = remove->next; - - switch (remove->type) { - case STR_PARAM: - if (remove->str) { - free(remove->str); - } - break; - - case FILE_PARAM: - if (remove->file.name) { - free(remove->file.name); - } - break; - } - - free(remove); - - if (next) - remove = next; - else break; - } - } -} - -static void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { - phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); - - if (!next) - return; - - *(next) = *(param); - - if (stack->top == NULL) { - stack->top = next; - stack->next = next; - } else { - stack->top->next = next; - next->top = stack->top; - stack->top = next; - } - - stack->len++; -} - -phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { - const phpdbg_command_t *command = commands; - phpdbg_param_t *name = *top; - phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; - ulong matches = 0L; - - while (command && command->name && command->handler) { - if (command->name_len >= name->len) { - if (memcmp(command->name, name->str, name->len) == SUCCESS) { - if (matches < 3) { - matched[matches] = command; - matches++; - } else break; - } - } - command++; - } - - switch (matches) { - case 0: { - asprintf( - why, - "The command %s could not be found", - name->str); - } break; - - case 1: { - (*top) = (*top)->next; - if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { - command = phpdbg_stack_resolve(matched[0]->subs, top, why); - if (command) { - return command; - } - } - - return matched[0]; - } break; - - default: { - asprintf( - why, - "The command %s is ambigious, matching %d commands", - name->str, matches); - } - } - - return NULL; -} - -int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { - phpdbg_param_t *command = NULL, - *params = NULL; - phpdbg_command_t *handler = NULL; - - if (stack->type != STACK_PARAM) { - asprintf( - why, "the passed argument was not a stack !!"); - return FAILURE; - } - - if (!stack->len) { - asprintf( - why, "the stack contains nothing !!"); - return FAILURE; - } - - command = (phpdbg_param_t*) stack->next; - - switch (command->type) { - case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); - - case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); - - case STR_PARAM: { - handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, &command, why); - - if (handler) { - return handler->handler(command, NULL TSRMLS_CC); - } else { - return FAILURE; - } - } break; - - default: - asprintf( - why, "the first parameter makes no sense !!"); - return FAILURE; - } - - return SUCCESS; -} - - /* Line 268 of yacc.c */ -#line 285 "sapi/phpdbg/phpdbg_parser.c" +#line 109 "sapi/phpdbg/phpdbg_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -304,7 +128,7 @@ int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { /* "%code requires" blocks. */ /* Line 288 of yacc.c */ -#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 39 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -315,7 +139,7 @@ typedef void* yyscan_t; /* Line 288 of yacc.c */ -#line 319 "sapi/phpdbg/phpdbg_parser.c" +#line 143 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -356,7 +180,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 360 "sapi/phpdbg/phpdbg_parser.c" +#line 184 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -648,11 +472,11 @@ static const yytype_int8 yyrhs[] = }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = +static const yytype_uint8 yyrline[] = { - 0, 251, 251, 255, 256, 260, 261, 265, 266, 270, - 271, 275, 276, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 294 + 0, 75, 75, 79, 80, 84, 85, 89, 90, 94, + 95, 99, 100, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 118 }; #endif @@ -1610,133 +1434,133 @@ yyreduce: case 3: /* Line 1806 of yacc.c */ -#line 255 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 4: /* Line 1806 of yacc.c */ -#line 256 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 7: /* Line 1806 of yacc.c */ -#line 265 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 89 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 8: /* Line 1806 of yacc.c */ -#line 266 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 90 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 9: /* Line 1806 of yacc.c */ -#line 270 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 94 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } break; case 10: /* Line 1806 of yacc.c */ -#line 271 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 95 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } break; case 12: /* Line 1806 of yacc.c */ -#line 276 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 13: /* Line 1806 of yacc.c */ -#line 280 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 104 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 281 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 282 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 283 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 107 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 284 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 108 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 285 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 109 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 286 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 110 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1806 of yacc.c */ -#line 287 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: /* Line 1806 of yacc.c */ -#line 288 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 22: /* Line 1806 of yacc.c */ -#line 289 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 113 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: /* Line 1806 of yacc.c */ -#line 290 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 114 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } break; /* Line 1806 of yacc.c */ -#line 1740 "sapi/phpdbg/phpdbg_parser.c" +#line 1564 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1967,6 +1791,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 296 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 120 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index b307843dec1..5c0ac4819e7 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -33,7 +33,7 @@ /* "%code requires" blocks. */ /* Line 2068 of yacc.c */ -#line 215 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 39 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 9a0946138c4..6aff5dd0d1a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -965,8 +965,6 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ input = phpdbg_read_input(NULL TSRMLS_CC); - printf("got input %s\n", input); - if (input) { do { yyscan_t scanner; From 366bf38b4f71e9aa51ee971b7a84a09fdff79680 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 19 Feb 2014 01:13:03 +0100 Subject: [PATCH 057/137] Oplines run from 0 to op_array->last - 1 See also in issue 76 --- phpdbg_bp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 609644548fa..b495bc711f4 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -355,7 +355,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC) /* {{{ */ { phpdbg_breakline_t opline_break; - if (op_array->last < brake->opline_num) { + if (op_array->last <= brake->opline_num) { if (brake->class_name == NULL) { phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); } else if (brake->func_name == NULL) { From e2e93ac259150fde9e3660838a2e836daa939acb Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 19 Feb 2014 00:33:49 +0000 Subject: [PATCH 058/137] work on parameters to commands --- phpdbg_break.c | 18 +++--- phpdbg_cmd.c | 158 ++++++++++++++++++++++++++++++++++++++++++------ phpdbg_cmd.h | 14 ++--- phpdbg_list.c | 8 +-- phpdbg_print.c | 6 +- phpdbg_prompt.c | 37 +++++++----- phpdbg_set.c | 10 +-- 7 files changed, 190 insertions(+), 61 deletions(-) diff --git a/phpdbg_break.c b/phpdbg_break.c index 67267550c54..870f68a481c 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -31,15 +31,15 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, 1), - PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, 1), - PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, 1), - PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, 1), - PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, 1), - PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1), - PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, 1), + PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, "f"), + PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, "s"), + PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, "m"), + PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, "a"), + PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, "s"), + PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, "c"), + PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), + PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "l"), + PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "l"), PHPDBG_END_COMMAND }; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 27b8e15de89..c0149b3ad23 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -471,11 +471,132 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) stack->len++; } /* }}} */ +PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param_t **stack, char **why TSRMLS_DC) { + if (command && command->args) { + const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; + const char *arg = command->args; + size_t expected = strlen(command->args), + received = 0L; + zend_bool optional = 0; + + if (*arg == '|') { + expected--; + optional = 1; + arg++; + } + + if (arg && !top && !optional) { + asprintf(why, + "%s expected arguments and received none", command->name); + return FAILURE; + } + + while (top && arg) { + + switch (*arg) { + case '|': { + expected--; + optional = 1; + arg++; + } continue; + + case 'i': if (top->type != STR_PARAM) { + asprintf(why, + "%s expected raw input and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 's': if (top->type != STR_PARAM) { + asprintf(why, + "%s expected string and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'n': if (top->type != NUMERIC_PARAM) { + asprintf(why, + "%s expected number and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'm': if (top->type != METHOD_PARAM) { + asprintf(why, + "%s expected method and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'a': if (top->type != ADDR_PARAM) { + asprintf(why, + "%s expected address and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'f': if (top->type != FILE_PARAM) { + asprintf(why, + "%s expected file:line and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'c': if (top->type != COND_PARAM) { + asprintf(why, + "%s expected condition and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case 'b': if (top->type != NUMERIC_PARAM) { + asprintf(why, + "%s expected boolean and got %s at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } else if (top->num > 1 || top->num < 0) { + asprintf(why, + "%s expected boolean and got number at parameter %d", + command->name, phpdbg_get_param_type(top TSRMLS_CC), + (command->args - arg) + 1); + return FAILURE; + } break; + + case '*': { /* do nothing */ } break; + } + top = top->next; + received++; + arg++; + } + + if ((received < expected) && (arg && *arg) && !optional) { + asprintf(why, + "%s expected %d arguments (%s) and received %d", + command->name, + expected, + command->args, + received); + return FAILURE; + } + } + + return SUCCESS; +} + /* {{{ */ -PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why) { +PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) { const phpdbg_command_t *command = commands; phpdbg_param_t *name = *top; phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; + ulong matches = 0L; while (command && command->name && command->handler) { @@ -491,23 +612,18 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman } switch (matches) { - case 0: { + case 0: if (!parent) { asprintf( why, "The command %s could not be found", name->str); - } break; + return NULL; + } else return parent; case 1: { (*top) = (*top)->next; - if (matched[0]->subs && (*top) && ((*top)->type == STR_PARAM)) { - command = phpdbg_stack_resolve(matched[0]->subs, top, why); - if (command) { - return command; - } - } - - return matched[0]; + + command = matched[0]; } break; default: { @@ -515,9 +631,15 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman why, "The command %s is ambigious, matching %d commands", name->str, matches); - } + } return NULL; } - + + if (command->subs && (*top) && ((*top)->type == STR_PARAM)) { + return phpdbg_stack_resolve(command->subs, command, top, why); + } else { + return command; + } + return NULL; } /* }}} */ @@ -550,14 +672,14 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { case STR_PARAM: { handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, &command, why); + phpdbg_prompt_commands, NULL, &command, why); if (handler) { - return handler->handler(command, NULL TSRMLS_CC); - } else { - return FAILURE; + if (phpdbg_stack_verify(handler, &command, why) == SUCCESS) { + return handler->handler(command, NULL TSRMLS_CC); + } } - } break; + } return FAILURE; default: asprintf( diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index d22650c6716..23766c62da4 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -105,7 +105,7 @@ struct _phpdbg_command_t { char alias; /* Alias */ phpdbg_command_handler_t handler; /* Command handler */ const phpdbg_command_t *subs; /* Sub Commands */ - char arg_type; /* Accept args? */ + char *args; /* Argument Spec */ }; /* }}} */ @@ -147,7 +147,7 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); * Stack Management */ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); -PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, phpdbg_param_t **top, char **why); +PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); @@ -168,17 +168,17 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) */ #define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name -#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, has_args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, has_args} +#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args} -#define PHPDBG_COMMAND_D(name, tip, alias, children, has_args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, has_args} +#define PHPDBG_COMMAND_D(name, tip, alias, children, args) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args} #define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) #define PHPDBG_COMMAND_ARGS param, input TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', '\0'} /* * Default Switch Case diff --git a/phpdbg_list.c b/phpdbg_list.c index 7177def8d62..a1bd8c0ff53 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -33,10 +33,10 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); const phpdbg_command_t phpdbg_list_commands[] = { - PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, 1), - PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, 1), + PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, "l"), + PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, "s"), + PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, "m"), + PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, "s"), PHPDBG_END_COMMAND }; diff --git a/phpdbg_print.c b/phpdbg_print.c index 7e549a27793..ed630c200c7 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -29,9 +29,9 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); const phpdbg_command_t phpdbg_print_commands[] = { PHPDBG_COMMAND_D_EX(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), PHPDBG_COMMAND_D_EX(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), - PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, 1), - PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, 1), - PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, 1), + PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"), + PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"), + PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"), PHPDBG_COMMAND_D_EX(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), PHPDBG_END_COMMAND }; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6aff5dd0d1a..1e1f048ebf8 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -44,29 +44,29 @@ int yyparse(phpdbg_param_t *stack, yyscan_t scanner); /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { - PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, 1), + PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"), PHPDBG_COMMAND_D(compile, "attempt compilation", 'c', NULL, 0), - PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 1), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, 0), - PHPDBG_COMMAND_D(eval, "evaluate some code", 'E', NULL, 1), + PHPDBG_COMMAND_D(eval, "evaluate some code", 'E', NULL, "i"), PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), - PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 2), - PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1), + PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, "s"), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 0), PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), - PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, 1), - PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2), - PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1), + PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "n"), + PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), + PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s"), PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0), PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), - PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 2), - PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1), - PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, 1), - PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, 1), - PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), - PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 1), + PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"), + PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, "b"), + PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), + PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, "s"), + PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 0), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -989,8 +989,10 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ }*/ phpdbg_error("%s", why); } - if (why) + if (why) { free(why); + why = NULL; + } break; case PHPDBG_LEAVE: @@ -1005,6 +1007,11 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } } + if (why) { + free(why); + why = NULL; + } + yy_delete_buffer(state, scanner); yylex_destroy(scanner); diff --git a/phpdbg_set.c b/phpdbg_set.c index 6280086da49..a0dac2ea5bb 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -27,13 +27,13 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); const phpdbg_command_t phpdbg_set_commands[] = { - PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, 0), + PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, "s"), #ifndef _WIN32 - PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, 1), - PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, 1), + PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, "ss"), + PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, "b"), #endif - PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, 0), - PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, 0), + PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, "s"), + PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, "lb"), PHPDBG_END_COMMAND }; From 996182993da1c35e8c35a3188b4c1adb764320f8 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 19 Feb 2014 08:33:54 +0000 Subject: [PATCH 059/137] remove input_t support single char aliases ... --- phpdbg.c | 10 ++--- phpdbg_bp.c | 2 +- phpdbg_bp.h | 2 +- phpdbg_break.c | 6 +-- phpdbg_cmd.c | 87 +++++++++++++++++++++++++-------------- phpdbg_cmd.h | 24 ++++------- phpdbg_help.c | 2 +- phpdbg_prompt.c | 107 +++++++++++++++++++++++++++--------------------- phpdbg_set.c | 15 ++++--- 9 files changed, 143 insertions(+), 112 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 7676687e712..0b748f0e85e 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -271,19 +271,19 @@ static PHP_FUNCTION(phpdbg_break) switch (type) { case METHOD_PARAM: - phpdbg_do_break_method(¶m, NULL TSRMLS_CC); + phpdbg_do_break_method(¶m TSRMLS_CC); break; case FILE_PARAM: - phpdbg_do_break_file(¶m, NULL TSRMLS_CC); + phpdbg_do_break_file(¶m TSRMLS_CC); break; case NUMERIC_PARAM: - phpdbg_do_break_lineno(¶m, NULL TSRMLS_CC); + phpdbg_do_break_lineno(¶m TSRMLS_CC); break; case STR_PARAM: - phpdbg_do_break_func(¶m, NULL TSRMLS_CC); + phpdbg_do_break_func(¶m TSRMLS_CC); break; default: zend_error( @@ -1232,7 +1232,7 @@ phpdbg_main: if (run) { /* no need to try{}, run does it ... */ - PHPDBG_COMMAND_HANDLER(run)(NULL, NULL TSRMLS_CC); + PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); if (run > 1) { /* if -r is on the command line more than once just quit */ goto phpdbg_out; diff --git a/phpdbg_bp.c b/phpdbg_bp.c index acb53450cb2..cacc48f13f9 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -760,7 +760,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l } } /* }}} */ -PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { /* if (input->argc > 3 && phpdbg_argv_is(2, "if")) { diff --git a/phpdbg_bp.h b/phpdbg_bp.h index b1a9ddf4749..97980e7ed78 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -119,7 +119,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_expression(const char* expression, size_t expression_len TSRMLS_DC); -PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC); /* }}} */ +PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC); /* }}} */ /* {{{ Breakpoint Detection API */ PHPDBG_API phpdbg_breakbase_t* phpdbg_find_breakpoint(zend_execute_data* TSRMLS_DC); /* }}} */ diff --git a/phpdbg_break.c b/phpdbg_break.c index 870f68a481c..aeaf5973f09 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -38,8 +38,8 @@ const phpdbg_command_t phpdbg_break_commands[] = { PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, "s"), PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, "c"), PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), - PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "l"), - PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "l"), + PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "n"), + PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), PHPDBG_END_COMMAND }; @@ -109,7 +109,7 @@ PHPDBG_BREAK(on) /* {{{ */ PHPDBG_BREAK(at) /* {{{ */ { - phpdbg_set_breakpoint_at(param, input TSRMLS_CC); + phpdbg_set_breakpoint_at(param TSRMLS_CC); return SUCCESS; } /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index c0149b3ad23..b678d393ab2 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -253,6 +253,10 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des break; case EMPTY_PARAM: { /* do nothing */ } break; + + default: { + /* not yet */ + } } } /* }}} */ @@ -302,6 +306,10 @@ PHPDBG_API zend_ulong phpdbg_hash_param(const phpdbg_param_t *param TSRMLS_DC) / break; case EMPTY_PARAM: { /* do nothing */ } break; + + default: { + /* not yet */ + } } return hash; @@ -371,6 +379,10 @@ PHPDBG_API zend_bool phpdbg_match_param(const phpdbg_param_t *l, const phpdbg_pa case EMPTY_PARAM: return 1; + + default: { + /* not yet */ + } } } } @@ -382,7 +394,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) if (param && param->type) { switch (param->type) { case STR_PARAM: - fprintf(stderr, "%s STR_PARAM(%s=%d)\n", msg, param->str, param->len); + fprintf(stderr, "%s STR_PARAM(%s=%lu)\n", msg, param->str, param->len); break; case ADDR_PARAM: @@ -390,7 +402,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) break; case FILE_PARAM: - fprintf(stderr, "%s FILE_PARAM(%s:%d)\n", msg, param->file.name, param->file.line); + fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); break; case METHOD_PARAM: @@ -402,7 +414,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) break; case NUMERIC_FUNCTION_PARAM: - fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%s)\n", msg, param->str, param->num); + fprintf(stderr, "%s NUMERIC_FUNCTION_PARAM(%s::%ld)\n", msg, param->str, param->num); break; case NUMERIC_PARAM: @@ -410,8 +422,12 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) break; case COND_PARAM: - fprintf(stderr, "%s COND_PARAM(%s=%d)\n", msg, param->str, param->len); + fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); break; + + default: { + /* not yet */ + } } } } /* }}} */ @@ -439,6 +455,10 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { free(remove->file.name); } break; + + default: { + /* nothing */ + } } free(remove); @@ -471,7 +491,7 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) stack->len++; } /* }}} */ -PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param_t **stack, char **why TSRMLS_DC) { +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { if (command && command->args) { const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; @@ -502,7 +522,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'i': if (top->type != STR_PARAM) { asprintf(why, - "%s expected raw input and got %s at parameter %d", + "%s expected raw input and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -510,7 +530,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 's': if (top->type != STR_PARAM) { asprintf(why, - "%s expected string and got %s at parameter %d", + "%s expected string and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -518,7 +538,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'n': if (top->type != NUMERIC_PARAM) { asprintf(why, - "%s expected number and got %s at parameter %d", + "%s expected number and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -526,7 +546,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'm': if (top->type != METHOD_PARAM) { asprintf(why, - "%s expected method and got %s at parameter %d", + "%s expected method and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -534,7 +554,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'a': if (top->type != ADDR_PARAM) { asprintf(why, - "%s expected address and got %s at parameter %d", + "%s expected address and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -542,7 +562,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'f': if (top->type != FILE_PARAM) { asprintf(why, - "%s expected file:line and got %s at parameter %d", + "%s expected file:line and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -550,7 +570,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'c': if (top->type != COND_PARAM) { asprintf(why, - "%s expected condition and got %s at parameter %d", + "%s expected condition and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; @@ -558,14 +578,14 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param case 'b': if (top->type != NUMERIC_PARAM) { asprintf(why, - "%s expected boolean and got %s at parameter %d", + "%s expected boolean and got %s at parameter %lu", command->name, phpdbg_get_param_type(top TSRMLS_CC), (command->args - arg) + 1); return FAILURE; } else if (top->num > 1 || top->num < 0) { asprintf(why, - "%s expected boolean and got number at parameter %d", - command->name, phpdbg_get_param_type(top TSRMLS_CC), + "%s expected boolean and got number at parameter %lu", + command->name, (command->args - arg) + 1); return FAILURE; } break; @@ -579,7 +599,7 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param if ((received < expected) && (arg && *arg) && !optional) { asprintf(why, - "%s expected %d arguments (%s) and received %d", + "%s expected %lu arguments (%s) and received %lu", command->name, expected, command->args, @@ -592,20 +612,28 @@ PHPDBG_API int phpdbg_stack_verify(phpdbg_command_t *command, const phpdbg_param } /* {{{ */ -PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) { +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why) { const phpdbg_command_t *command = commands; phpdbg_param_t *name = *top; - phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; - + const phpdbg_command_t *matched[3] = {NULL, NULL, NULL}; ulong matches = 0L; while (command && command->name && command->handler) { - if (command->name_len >= name->len) { - if (memcmp(command->name, name->str, name->len) == SUCCESS) { - if (matches < 3) { + if ((name->len == 1) || (command->name_len >= name->len)) { + /* match single letter alias */ + if (command->alias && (name->len == 1)) { + if (command->alias == (*name->str)) { matched[matches] = command; matches++; - } else break; + } + } else { + /* match full command name */ + if (memcmp(command->name, name->str, name->len) == SUCCESS) { + if (matches < 3) { + matched[matches] = command; + matches++; + } else break; + } } } command++; @@ -629,7 +657,7 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman default: { asprintf( why, - "The command %s is ambigious, matching %d commands", + "The command %s is ambigious, matching %lu commands", name->str, matches); } return NULL; } @@ -645,9 +673,8 @@ PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *comman /* {{{ */ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { - phpdbg_param_t *command = NULL, - *params = NULL; - phpdbg_command_t *handler = NULL; + phpdbg_param_t *command = NULL; + const phpdbg_command_t *handler = NULL; if (stack->type != STACK_PARAM) { asprintf( @@ -665,10 +692,10 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (command->type) { case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(eval)(command, NULL TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(eval)(command TSRMLS_CC); case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(shell)(command, NULL TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(shell)(command TSRMLS_CC); case STR_PARAM: { handler = phpdbg_stack_resolve( @@ -676,7 +703,7 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { if (handler) { if (phpdbg_stack_verify(handler, &command, why) == SUCCESS) { - return handler->handler(command, NULL TSRMLS_CC); + return handler->handler(command TSRMLS_CC); } } } return FAILURE; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 23766c62da4..da2a25cbbd1 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -23,8 +23,6 @@ #include "TSRM.h" -typedef struct _phpdbg_command_t phpdbg_command_t; - /* {{{ Command and Parameter */ enum { NO_ARG = 0, @@ -48,16 +46,6 @@ typedef enum { ORIG_PARAM } phpdbg_param_type; -typedef struct _phpdbg_input_t phpdbg_input_t; - -struct _phpdbg_input_t { - char * const *start; - char *string; - size_t length; - phpdbg_input_t **argv; - int argc; -}; - typedef struct _phpdbg_param phpdbg_param_t; struct _phpdbg_param { phpdbg_param_type type; @@ -95,8 +83,9 @@ struct _phpdbg_param { #define YYSTYPE phpdbg_param_t #endif -typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t*, const phpdbg_input_t* TSRMLS_DC); +typedef int (*phpdbg_command_handler_t)(const phpdbg_param_t* TSRMLS_DC); +typedef struct _phpdbg_command_t phpdbg_command_t; struct _phpdbg_command_t { const char *name; /* Command name */ size_t name_len; /* Command name length */ @@ -147,7 +136,8 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); * Stack Management */ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); -PHPDBG_API phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); +PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); +PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC); PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); @@ -174,11 +164,11 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) #define PHPDBG_COMMAND_D(name, tip, alias, children, args) \ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args} -#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param, const phpdbg_input_t *input TSRMLS_DC) +#define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param TSRMLS_DC) -#define PHPDBG_COMMAND_ARGS param, input TSRMLS_CC +#define PHPDBG_COMMAND_ARGS param TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', '\0'} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} /* * Default Switch Case diff --git a/phpdbg_help.c b/phpdbg_help.c index 8dcc89007d0..d3404f5569b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -240,7 +240,7 @@ PHPDBG_COMMAND(help) /* {{{ */ if (n>0) { if (cmd->alias == 'a') { /* help aliases executes a canned routine */ - return cmd->handler(param, NULL TSRMLS_CC); + return cmd->handler(param TSRMLS_CC); } else { pretty_print(get_help(cmd->name TSRMLS_CC) TSRMLS_CC); return SUCCESS; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 1e1f048ebf8..aed1f4a0156 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -73,66 +73,81 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -static inline int phpdbg_call_register(phpdbg_input_t *input TSRMLS_DC) /* {{{ */ +static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ */ { - phpdbg_input_t *function = input->argv[0]; + phpdbg_param_t *name = stack; - if (zend_hash_exists( - &PHPDBG_G(registered), function->string, function->length+1)) { + if (name->type == STR_PARAM) { + if (zend_hash_exists( + &PHPDBG_G(registered), name->str, name->len+1)) { - zval fname, *fretval; - zend_fcall_info fci; + zval fname, *fretval; + zend_fcall_info fci; - ZVAL_STRINGL(&fname, function->string, function->length, 1); + ZVAL_STRINGL(&fname, name->str, name->len, 1); - memset(&fci, 0, sizeof(zend_fcall_info)); + memset(&fci, 0, sizeof(zend_fcall_info)); - fci.size = sizeof(zend_fcall_info); - fci.function_table = &PHPDBG_G(registered); - fci.function_name = &fname; - fci.symbol_table = EG(active_symbol_table); - fci.object_ptr = NULL; - fci.retval_ptr_ptr = &fretval; - fci.no_separation = 1; + fci.size = sizeof(zend_fcall_info); + fci.function_table = &PHPDBG_G(registered); + fci.function_name = &fname; + fci.symbol_table = EG(active_symbol_table); + fci.object_ptr = NULL; + fci.retval_ptr_ptr = &fretval; + fci.no_separation = 1; - if (input->argc > 1) { - int param; - zval params; + if (stack->next) { + zval params; + phpdbg_param_t *next = stack->next; + + array_init(¶ms); - array_init(¶ms); + while (next) { + switch (next->type) { + case STR_PARAM: + add_next_index_stringl( + ¶ms, + next->str, + next->len, 1); + break; + + case NUMERIC_PARAM: + add_next_index_long(¶ms, next->num); + break; + + default: { + /* not yet */ + } + } + + phpdbg_debug( + "created param[%d] from argv[%d]: %s", + param, param+1, next->str); + next = next->next; + } - for (param = 0; param < (input->argc-1); param++) { - add_next_index_stringl( - ¶ms, - input->argv[param+1]->string, - input->argv[param+1]->length, 1); - - phpdbg_debug( - "created param[%d] from argv[%d]: %s", - param, param+1, input->argv[param+1]->string); + zend_fcall_info_args(&fci, ¶ms TSRMLS_CC); + } else { + fci.params = NULL; + fci.param_count = 0; } - zend_fcall_info_args(&fci, ¶ms TSRMLS_CC); - } else { - fci.params = NULL; - fci.param_count = 0; - } + phpdbg_debug( + "created %d params from arguments", + fci.param_count); - phpdbg_debug( - "created %d params from %d arguments", - fci.param_count, input->argc); + zend_call_function(&fci, NULL TSRMLS_CC); - zend_call_function(&fci, NULL TSRMLS_CC); + if (fretval) { + zend_print_zval_r( + fretval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + } - if (fretval) { - zend_print_zval_r( - fretval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); - } + zval_dtor(&fname); - zval_dtor(&fname); - - return SUCCESS; + return SUCCESS; + } } return FAILURE; @@ -1027,7 +1042,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ last: if (PHPDBG_G(lcmd)) { ret = PHPDBG_G(lcmd)->handler( - &PHPDBG_G(lparam), input TSRMLS_CC); + &PHPDBG_G(lparam) TSRMLS_CC); goto out; } } diff --git a/phpdbg_set.c b/phpdbg_set.c index a0dac2ea5bb..7ce67d934d0 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -69,7 +69,7 @@ PHPDBG_SET(break) /* {{{ */ break; case NUMERIC_PARAM: { - if (input && input->argc > 2) { + if (param->next) { /* if (phpdbg_argv_is(2, "on")) { phpdbg_enable_breakpoint(param->num TSRMLS_CC); @@ -99,14 +99,13 @@ PHPDBG_SET(break) /* {{{ */ #ifndef _WIN32 PHPDBG_SET(color) /* {{{ */ { - if ((param->type == STR_PARAM) && (input->argc == 3)) { + /*if ((param->type == STR_PARAM) && (input->argc == 3)) { const phpdbg_color_t *color = phpdbg_get_color( input->argv[2]->string, input->argv[2]->length TSRMLS_CC); int element = PHPDBG_COLOR_INVALID; - /* @TODO(anyone) make this consistent with other set commands */ if (color) { - /*if (phpdbg_argv_is(1, "prompt")) { + if (phpdbg_argv_is(1, "prompt")) { phpdbg_notice( "setting prompt color to %s (%s)", color->name, color->code); element = PHPDBG_COLOR_PROMPT; @@ -125,9 +124,8 @@ PHPDBG_SET(color) /* {{{ */ element = PHPDBG_COLOR_NOTICE; } else goto usage; -*/ - /* set color for element */ - /* phpdbg_set_color(element, color TSRMLS_CC); */ + + phpdbg_set_color(element, color TSRMLS_CC); } else { phpdbg_error( "Failed to find the requested color (%s)", input->argv[2]->string); @@ -136,7 +134,8 @@ PHPDBG_SET(color) /* {{{ */ usage: phpdbg_error( "set color used incorrectly: set color "); - } + } */ + return SUCCESS; } /* }}} */ From e2fcc870e34510dc4cc47ad69d77b28ae9eb21df Mon Sep 17 00:00:00 2001 From: krakjoe Date: Wed, 19 Feb 2014 20:18:49 +0000 Subject: [PATCH 060/137] work on lexer to be more permissive (accept moar strings) work on parameter parsing and command resolution work on error reporting for failed arguments update most commands move quiet to set quiet move set break on/off to set breaks on/off keep set break for set break update help accordingly --- dev/phpdbg_lexer.l | 12 +- phpdbg_break.c | 22 ++- phpdbg_cmd.c | 199 +++++++++++++---------- phpdbg_cmd.h | 12 +- phpdbg_help.c | 23 +-- phpdbg_info.c | 20 ++- phpdbg_lexer.c | 397 ++++++++++++++++++++++++--------------------- phpdbg_lexer.h | 2 +- phpdbg_list.c | 18 +- phpdbg_print.c | 15 +- phpdbg_prompt.c | 106 +++++------- phpdbg_prompt.h | 1 - phpdbg_set.c | 140 ++++++++-------- phpdbg_set.h | 2 + 14 files changed, 495 insertions(+), 474 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 46137d66768..e20f9dcc933 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -33,16 +33,16 @@ C_EVAL ?i:"eval" C_SHELL ?i:"shell" C_IF ?i:"if" -DIGITS [0-9]+ -ID [a-zA-Z_\x7f-\xff\-][a-zA-Z0-9_\x7f-\xff\-\./]* +WS [ \r\n\t]+ +DIGITS [0-9\.]+ +ID [^ \r\n\t]+ NSID [\\\\]?{ID} METHOD {NSID}+::{ID} NUMERIC_METHOD {METHOD}[#]{DIGITS} NUMERIC_FUNCTION {NSID}[#]{DIGITS} -FILE [^ :]+:[0-9]+ +FILE [^ :\r\n\t]+:[0-9]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" -WS [ \r\n\t]+ INPUT [^\n]+ %% @@ -129,8 +129,4 @@ INPUT [^\n]+ return T_INPUT; } {WS} { /* ignore whitespace */ } -. { - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_UNEXPECTED; -} %% diff --git a/phpdbg_break.c b/phpdbg_break.c index aeaf5973f09..fdf4e198b5e 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -24,22 +24,26 @@ #include "phpdbg_opcode.h" #include "phpdbg_break.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_BREAK_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[10]) + /** * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, "f"), - PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, "s"), - PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, "m"), - PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, "a"), - PHPDBG_COMMAND_D_EX(op, "specify breakpoint by opcode", 'O', break_op, NULL, "s"), - PHPDBG_COMMAND_D_EX(on, "specify breakpoint by condition", 'o', break_on, NULL, "c"), - PHPDBG_COMMAND_D_EX(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), - PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "n"), - PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), + PHPDBG_BREAK_COMMAND_D(file, "specify breakpoint by file:line", 'F', break_file, NULL, "f"), + PHPDBG_BREAK_COMMAND_D(func, "specify breakpoint by global function name", 'f', break_func, NULL, "s"), + PHPDBG_BREAK_COMMAND_D(method, "specify breakpoint by class::method", 'm', break_method, NULL, "m"), + PHPDBG_BREAK_COMMAND_D(address, "specify breakpoint by address", 'a', break_address, NULL, "a"), + PHPDBG_BREAK_COMMAND_D(op, "specify breakpoint by opcode", 'O', break_op, NULL, "s"), + PHPDBG_BREAK_COMMAND_D(on, "specify breakpoint by condition", 'o', break_on, NULL, "c"), + PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), + PHPDBG_BREAK_COMMAND_D(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "n"), + PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), PHPDBG_END_COMMAND }; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index b678d393ab2..4e6ef048b82 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -26,6 +26,23 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +static inline const char *phpdbg_command_name(const phpdbg_command_t *command, char *buffer) { + size_t pos = 0; + + if (command->parent) { + memcpy(&buffer[pos], command->parent->name, command->parent->name_len); + pos += command->parent->name_len; + memcpy(&buffer[pos], " ", sizeof(" ")-1); + pos += (sizeof(" ")-1); + } + + memcpy(&buffer[pos], command->name, command->name_len); + pos += command->name_len; + buffer[pos] = 0; + + return buffer; +} + PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { switch (param->type) { @@ -493,115 +510,87 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { if (command && command->args) { + char buffer[128] = {0,}; const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; - size_t expected = strlen(command->args), - received = 0L; + size_t least = 0L, + received = 0L, + current = 0L; zend_bool optional = 0; - if (*arg == '|') { - expected--; - optional = 1; + /* check for arg spec */ + if (!(arg) || !(*arg)) + return SUCCESS; + + least = 0L; + + /* count least amount of arguments */ + while (arg && *arg) { + if (arg[0] == '|') { + break; + } + least++; arg++; } - if (arg && !top && !optional) { - asprintf(why, - "%s expected arguments and received none", command->name); - return FAILURE; - } + arg = command->args; - while (top && arg) { +#define verify_arg(e, a, t) if (!(a)) { \ + if (!optional) { \ + asprintf(why, \ + "%s expected %s and got nothing at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e), \ + current); \ + return FAILURE;\ + } \ +} else if ((a)->type != (t)) { \ + asprintf(why, \ + "%s expected %s and got %s at parameter %lu", \ + phpdbg_command_name(command, buffer), \ + (e),\ + phpdbg_get_param_type((a) TSRMLS_CC), \ + current); \ + return FAILURE; \ +} + while (arg) { + current++; + switch (*arg) { - case '|': { - expected--; + case '|': { + current--; optional = 1; arg++; } continue; - case 'i': if (top->type != STR_PARAM) { - asprintf(why, - "%s expected raw input and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 's': if (top->type != STR_PARAM) { - asprintf(why, - "%s expected string and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'n': if (top->type != NUMERIC_PARAM) { - asprintf(why, - "%s expected number and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'm': if (top->type != METHOD_PARAM) { - asprintf(why, - "%s expected method and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'a': if (top->type != ADDR_PARAM) { - asprintf(why, - "%s expected address and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'f': if (top->type != FILE_PARAM) { - asprintf(why, - "%s expected file:line and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'c': if (top->type != COND_PARAM) { - asprintf(why, - "%s expected condition and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } break; - - case 'b': if (top->type != NUMERIC_PARAM) { - asprintf(why, - "%s expected boolean and got %s at parameter %lu", - command->name, phpdbg_get_param_type(top TSRMLS_CC), - (command->args - arg) + 1); - return FAILURE; - } else if (top->num > 1 || top->num < 0) { - asprintf(why, - "%s expected boolean and got number at parameter %lu", - command->name, - (command->args - arg) + 1); - return FAILURE; - } break; + case 'i': verify_arg("raw input", top, STR_PARAM); break; + case 's': verify_arg("string", top, STR_PARAM); break; + case 'n': verify_arg("number", top, NUMERIC_PARAM); break; + case 'm': verify_arg("method", top, METHOD_PARAM); break; + case 'a': verify_arg("address", top, ADDR_PARAM); break; + case 'f': verify_arg("file:line", top, FILE_PARAM); break; + case 'c': verify_arg("condition", top, COND_PARAM); break; + case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; case '*': { /* do nothing */ } break; } - top = top->next; + + if (top ) { + top = top->next; + } else break; + received++; arg++; } - if ((received < expected) && (arg && *arg) && !optional) { +#undef verify_arg + + if ((received < least)) { asprintf(why, - "%s expected %lu arguments (%s) and received %lu", - command->name, - expected, + "%s expected at least %lu arguments (%s) and received %lu", + phpdbg_command_name(command, buffer), + least, command->args, received); return FAILURE; @@ -627,15 +616,21 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * matches++; } } else { + /* match full command name */ if (memcmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { matched[matches] = command; matches++; + + /* exact match */ + if (name->len == command->name_len) + break; } else break; } } } + command++; } @@ -655,10 +650,36 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } break; default: { + char *list = NULL; + zend_uint it = 0; + size_t pos = 0; + + while (it < matches) { + if (!list) { + list = malloc( + matched[it]->name_len + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } else { + list = realloc(list, + (pos + matched[it]->name_len) + 1 + + ((it+1) < matches ? sizeof(", ")-1 : 0)); + } + memcpy(&list[pos], matched[it]->name, matched[it]->name_len); + pos += matched[it]->name_len; + if ((it+1) < matches) { + memcpy(&list[pos], ", ", sizeof(", ")-1); + pos += (sizeof(", ") - 1); + } + + list[pos] = 0; + it++; + } + asprintf( why, - "The command %s is ambigious, matching %lu commands", - name->str, matches); + "The command %s is ambigious, matching %lu commands (%s)", + name->str, matches, list); + free(list); } return NULL; } diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index da2a25cbbd1..2c0ecb4540f 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -94,7 +94,8 @@ struct _phpdbg_command_t { char alias; /* Alias */ phpdbg_command_handler_t handler; /* Command handler */ const phpdbg_command_t *subs; /* Sub Commands */ - char *args; /* Argument Spec */ + char *args; /* Argument Spec */ + const phpdbg_command_t *parent; /* Parent Command */ }; /* }}} */ @@ -158,17 +159,20 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) */ #define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name +#define PHPDBG_COMMAND_D_EXP(name, tip, alias, handler, children, args, parent) \ + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, parent} + #define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args} + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, args, NULL} #define PHPDBG_COMMAND_D(name, tip, alias, children, args) \ - {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args} + {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, args, NULL} #define PHPDBG_COMMAND(name) int phpdbg_do_##name(const phpdbg_param_t *param TSRMLS_DC) #define PHPDBG_COMMAND_ARGS param TSRMLS_CC -#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'} +#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0', NULL} /* * Default Switch Case diff --git a/phpdbg_help.c b/phpdbg_help.c index d3404f5569b..c5da19b9881 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -809,21 +809,6 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Print the instructions for the current stack" }, -{"quiet", -"Setting quietness on will stop the OPLINE output during execution" CR CR - -"**Examples**" CR CR -" $P quiet 1" CR -" $P Q 1" CR -" Will silence OPLINE output, while" CR CR - -" $P quiet 0" CR -" $P Q 0" CR -" Will enable OPLINE output again" CR CR - -"Note: Quietness is disabled automatically while stepping" -}, - {"register", //******* Needs a general explanation of the how registered functions work "Register any global function for use as a command in phpdbg console" CR CR @@ -856,11 +841,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { "are as follows:" CR CR " **Type** **Alias** **Purpose**" CR -" **prompt** **p** set the prompt " CR +" **prompt** **p** set the prompt" CR " **color** **c** set color " CR -" **colors** **C** set colors on or off" CR +" **colors** **C** set colors " CR " **oplog** **O** set oplog output" CR -" **break** **b** set break **id** " CR CR +" **break** **b** set break **id** " CR +" **breaks** **B** set breaks " CR +" **quiet** **q** set quiet " CR CR "Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, " "**cyan** and **black**. All colours except **none** can be followed by an optional " diff --git a/phpdbg_info.c b/phpdbg_info.c index b559b75835f..97f88bfa1ec 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -23,18 +23,22 @@ #include "phpdbg_utils.h" #include "phpdbg_info.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_INFO_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[14]) + const phpdbg_command_t phpdbg_info_commands[] = { - PHPDBG_COMMAND_D_EX(break, "show breakpoints", 'b', info_break, NULL, 0), - PHPDBG_COMMAND_D_EX(files, "show included files", 'F', info_files, NULL, 0), - PHPDBG_COMMAND_D_EX(classes, "show loaded classes", 'c', info_classes, NULL, 0), - PHPDBG_COMMAND_D_EX(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), - PHPDBG_COMMAND_D_EX(error, "show last error", 'e', info_error, NULL, 0), - PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0), - PHPDBG_COMMAND_D_EX(literal, "show active literal constants", 'l', info_literal, NULL, 0), - PHPDBG_COMMAND_D_EX(memory, "show memory manager stats", 'm', info_memory, NULL, 0), + PHPDBG_INFO_COMMAND_D(break, "show breakpoints", 'b', info_break, NULL, 0), + PHPDBG_INFO_COMMAND_D(files, "show included files", 'F', info_files, NULL, 0), + PHPDBG_INFO_COMMAND_D(classes, "show loaded classes", 'c', info_classes, NULL, 0), + PHPDBG_INFO_COMMAND_D(funcs, "show loaded classes", 'f', info_funcs, NULL, 0), + PHPDBG_INFO_COMMAND_D(error, "show last error", 'e', info_error, NULL, 0), + PHPDBG_INFO_COMMAND_D(vars, "show active variables", 'v', info_vars, NULL, 0), + PHPDBG_INFO_COMMAND_D(literal, "show active literal constants", 'l', info_literal, NULL, 0), + PHPDBG_INFO_COMMAND_D(memory, "show memory manager stats", 'm', info_memory, NULL, 0), PHPDBG_END_COMMAND }; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 9999a639786..4515b6d822e 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 16 +#define YY_END_OF_BUFFER 17 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,19 +358,21 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[96] = +static yyconst flex_int16_t yy_accept[112] = { 0, - 0, 0, 0, 0, 18, 16, 15, 15, 15, 16, - 13, 6, 6, 16, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 16, 14, 14, 15, 0, 0, 15, - 15, 0, 0, 12, 0, 0, 0, 13, 13, 0, - 0, 6, 0, 13, 13, 13, 13, 3, 5, 13, - 4, 13, 13, 13, 13, 14, 14, 10, 12, 0, - 10, 8, 0, 0, 11, 13, 13, 13, 13, 5, - 13, 13, 4, 9, 0, 0, 13, 13, 1, 13, - 13, 4, 0, 9, 13, 13, 5, 2, 7, 13, - 13, 13, 4, 5, 0 + 0, 0, 0, 0, 17, 13, 15, 13, 6, 6, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 14, 14, 13, 13, 13, 13, 15, 13, 0, + 12, 13, 13, 13, 6, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 3, 5, 13, 4, 13, 13, + 13, 14, 14, 8, 10, 13, 12, 0, 8, 13, + 12, 13, 10, 13, 13, 13, 11, 8, 13, 13, + 13, 13, 5, 13, 13, 4, 9, 9, 9, 9, + 13, 8, 9, 9, 9, 9, 9, 13, 13, 13, + 1, 13, 13, 4, 9, 8, 9, 8, 9, 13, + 13, 5, 2, 7, 7, 13, 13, 13, 4, 5, + 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -378,190 +380,230 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 7, 8, 8, 9, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 11, 1, 1, - 1, 1, 1, 1, 12, 13, 14, 15, 16, 17, - 7, 18, 19, 7, 7, 20, 7, 21, 22, 7, - 7, 23, 24, 25, 26, 27, 7, 7, 28, 7, - 1, 29, 1, 1, 7, 1, 30, 31, 14, 32, + 1, 2, 1, 4, 5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 6, 1, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, + 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, + 1, 16, 17, 1, 1, 18, 1, 19, 20, 1, + 1, 21, 22, 23, 24, 25, 1, 1, 26, 1, + 1, 27, 1, 1, 1, 1, 28, 29, 12, 30, - 33, 34, 7, 35, 36, 7, 7, 37, 7, 38, - 39, 7, 7, 40, 41, 42, 43, 44, 7, 45, - 46, 7, 1, 1, 1, 1, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 31, 32, 1, 33, 34, 1, 1, 35, 1, 36, + 37, 1, 1, 38, 39, 40, 41, 42, 1, 43, + 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[47] = +static yyconst flex_int32_t yy_meta[45] = { 0, - 1, 1, 2, 3, 1, 4, 5, 4, 4, 4, - 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 1, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5 + 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[107] = +static yyconst flex_int16_t yy_base[121] = { 0, - 0, 0, 45, 48, 148, 133, 51, 54, 57, 59, - 88, 57, 62, 448, 117, 65, 94, 95, 113, 120, - 115, 64, 124, 160, 0, 72, 75, 105, 71, 170, - 173, 174, 116, 94, 177, 104, 181, 119, 123, 184, - 206, 187, 227, 164, 215, 234, 182, 128, 148, 213, - 185, 236, 237, 243, 212, 0, 220, 101, 448, 92, - 266, 272, 0, 295, 0, 280, 255, 289, 266, 214, - 292, 298, 258, 79, 334, 0, 302, 328, 294, 333, - 331, 322, 216, 76, 334, 340, 336, 338, 219, 359, - 362, 364, 361, 363, 448, 400, 405, 410, 415, 420, + 0, 0, 43, 45, 106, 44, 48, 52, 57, 80, + 63, 64, 119, 65, 90, 92, 157, 99, 73, 104, + 116, 0, 56, 125, 142, 132, 148, 74, 176, 56, + 155, 202, 228, 165, 189, 251, 212, 217, 240, 241, + 248, 264, 267, 279, 280, 281, 294, 291, 296, 293, + 306, 0, 100, 330, 335, 320, 628, 93, 0, 346, + 347, 373, 180, 356, 361, 193, 0, 384, 389, 392, + 397, 400, 399, 420, 409, 425, 426, 436, 441, 449, + 206, 0, 457, 460, 486, 212, 469, 234, 470, 493, + 477, 496, 498, 503, 529, 534, 324, 0, 361, 539, - 425, 430, 435, 64, 440, 442 + 540, 541, 542, 570, 378, 575, 577, 578, 554, 583, + 628, 610, 79, 613, 66, 616, 618, 621, 51, 624 } ; -static yyconst flex_int16_t yy_def[107] = +static yyconst flex_int16_t yy_def[121] = { 0, - 95, 1, 96, 96, 95, 97, 97, 97, 95, 98, - 99, 97, 97, 95, 99, 15, 15, 15, 15, 15, - 15, 15, 15, 100, 101, 101, 95, 97, 95, 97, - 95, 98, 102, 97, 102, 98, 97, 15, 15, 95, - 103, 97, 97, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 101, 101, 95, 95, 102, - 102, 97, 104, 105, 43, 15, 15, 15, 15, 15, - 15, 15, 15, 106, 105, 75, 15, 15, 15, 15, - 15, 15, 95, 106, 15, 15, 15, 15, 95, 15, - 15, 15, 15, 15, 0, 95, 95, 95, 95, 95, + 111, 1, 112, 112, 111, 113, 111, 114, 113, 113, + 115, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 116, 116, 113, 113, 115, 113, 111, 114, 117, + 113, 114, 118, 114, 113, 113, 115, 115, 115, 115, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 116, 116, 113, 115, 119, 111, 117, 32, 118, + 115, 118, 62, 120, 118, 32, 36, 115, 113, 113, + 113, 113, 113, 113, 113, 113, 119, 119, 119, 119, + 62, 62, 120, 119, 120, 85, 120, 62, 113, 113, + 113, 113, 113, 113, 119, 119, 85, 85, 85, 113, - 95, 95, 95, 95, 95, 95 + 113, 113, 113, 119, 85, 113, 113, 113, 113, 113, + 0, 111, 111, 111, 111, 111, 111, 111, 111, 111 } ; -static yyconst flex_int16_t yy_nxt[495] = +static yyconst flex_int16_t yy_nxt[673] = { 0, - 6, 7, 8, 9, 10, 6, 11, 6, 12, 13, - 14, 11, 11, 11, 15, 16, 17, 11, 18, 11, - 19, 20, 11, 21, 22, 11, 11, 23, 24, 11, - 11, 15, 16, 17, 11, 18, 11, 19, 20, 11, - 21, 22, 11, 11, 11, 23, 26, 27, 26, 26, - 27, 26, 30, 30, 31, 30, 30, 31, 31, 31, - 31, 29, 33, 34, 29, 42, 42, 29, 74, 35, - 42, 42, 29, 57, 31, 57, 31, 31, 31, 58, - 58, 83, 38, 38, 83, 45, 53, 36, 28, 28, - 28, 46, 28, 37, 95, 39, 39, 39, 40, 38, + 6, 7, 7, 8, 6, 9, 10, 9, 11, 6, + 6, 6, 12, 13, 14, 6, 15, 6, 16, 17, + 6, 18, 19, 6, 6, 20, 21, 6, 6, 12, + 13, 14, 6, 15, 6, 16, 17, 6, 18, 19, + 6, 6, 6, 20, 23, 7, 23, 7, 25, 28, + 28, 77, 26, 30, 30, 31, 32, 53, 28, 57, + 33, 25, 35, 35, 35, 26, 37, 38, 25, 25, + 27, 39, 26, 26, 44, 28, 28, 25, 34, 24, + 41, 26, 58, 27, 25, 35, 35, 35, 26, 40, + 27, 27, 44, 50, 25, 111, 25, 41, 26, 27, - 38, 43, 45, 53, 29, 47, 28, 33, 46, 58, - 58, 48, 38, 38, 35, 29, 41, 28, 28, 28, - 59, 28, 37, 47, 39, 39, 39, 40, 48, 38, - 38, 38, 52, 38, 49, 44, 50, 38, 38, 54, - 51, 38, 38, 29, 60, 41, 38, 95, 38, 52, - 38, 49, 44, 50, 38, 38, 54, 51, 38, 38, - 28, 28, 28, 38, 28, 28, 38, 28, 28, 28, - 29, 30, 30, 31, 31, 31, 31, 33, 34, 95, - 29, 59, 38, 38, 35, 61, 61, 66, 28, 62, - 62, 29, 58, 58, 63, 42, 42, 29, 95, 38, + 26, 53, 28, 25, 45, 111, 27, 26, 25, 111, + 50, 46, 26, 111, 49, 111, 27, 51, 27, 111, + 25, 45, 36, 25, 26, 27, 111, 26, 46, 25, + 27, 49, 111, 26, 51, 111, 38, 42, 55, 55, + 56, 111, 27, 43, 111, 27, 25, 54, 54, 54, + 26, 27, 25, 111, 42, 111, 26, 111, 40, 25, + 43, 25, 111, 26, 111, 26, 30, 111, 27, 32, + 111, 47, 111, 33, 27, 48, 111, 30, 30, 31, + 32, 27, 111, 27, 33, 60, 63, 63, 47, 111, + 111, 66, 48, 25, 35, 35, 35, 26, 29, 29, - 38, 69, 36, 38, 66, 60, 28, 28, 28, 95, - 28, 28, 95, 28, 28, 28, 29, 38, 69, 95, - 38, 57, 31, 57, 89, 89, 67, 89, 89, 70, - 38, 38, 38, 38, 28, 65, 65, 29, 65, 65, - 65, 65, 65, 65, 67, 68, 70, 38, 38, 38, - 38, 71, 38, 95, 38, 38, 65, 65, 65, 65, - 65, 38, 72, 68, 95, 95, 73, 78, 71, 38, - 59, 38, 38, 38, 61, 61, 38, 95, 38, 72, - 62, 62, 29, 73, 38, 78, 95, 95, 95, 80, - 38, 77, 95, 38, 60, 28, 28, 28, 38, 28, + 29, 111, 34, 30, 30, 31, 32, 59, 59, 59, + 33, 60, 60, 60, 64, 27, 38, 83, 83, 83, + 39, 38, 68, 68, 68, 39, 111, 111, 34, 30, + 30, 61, 62, 111, 63, 63, 64, 111, 40, 60, + 60, 60, 111, 40, 38, 38, 111, 111, 56, 39, + 111, 111, 25, 111, 65, 25, 26, 67, 67, 26, + 67, 67, 67, 67, 67, 67, 40, 40, 25, 69, + 111, 25, 26, 70, 27, 26, 71, 27, 67, 67, + 67, 67, 67, 25, 25, 25, 69, 26, 26, 26, + 27, 70, 111, 27, 71, 25, 72, 25, 25, 26, - 28, 38, 76, 76, 76, 40, 80, 38, 79, 77, - 38, 81, 38, 82, 85, 38, 38, 95, 95, 95, - 38, 95, 95, 41, 38, 79, 95, 38, 81, 38, - 82, 95, 85, 38, 28, 28, 28, 38, 28, 28, - 38, 76, 76, 76, 40, 95, 38, 86, 87, 38, - 88, 38, 38, 90, 38, 91, 38, 38, 38, 95, - 95, 95, 41, 38, 86, 87, 38, 88, 38, 38, - 90, 38, 91, 38, 92, 38, 93, 38, 94, 38, - 38, 38, 38, 95, 95, 95, 95, 95, 95, 95, - 95, 92, 95, 93, 38, 94, 38, 38, 38, 38, + 25, 26, 26, 111, 26, 27, 27, 27, 73, 74, + 25, 111, 111, 72, 26, 111, 75, 27, 111, 27, + 27, 111, 27, 111, 78, 73, 74, 76, 79, 105, + 105, 105, 27, 75, 25, 54, 54, 54, 26, 38, + 111, 55, 55, 39, 76, 111, 80, 30, 30, 61, + 62, 38, 111, 111, 81, 39, 27, 30, 30, 84, + 85, 40, 30, 111, 86, 62, 83, 83, 83, 81, + 111, 111, 65, 40, 30, 30, 61, 62, 82, 82, + 82, 81, 87, 105, 105, 105, 111, 88, 38, 68, + 68, 68, 39, 25, 111, 111, 25, 26, 89, 65, - 25, 25, 25, 25, 25, 28, 28, 95, 28, 28, - 32, 32, 32, 32, 32, 38, 38, 95, 38, 38, - 55, 55, 95, 55, 55, 56, 95, 56, 56, 56, - 33, 33, 33, 33, 33, 64, 64, 95, 64, 64, - 75, 75, 95, 75, 75, 84, 84, 5, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95 + 26, 25, 90, 25, 25, 26, 111, 26, 26, 111, + 40, 111, 111, 25, 91, 27, 89, 26, 27, 111, + 90, 92, 94, 27, 25, 27, 27, 111, 26, 25, + 95, 91, 111, 26, 79, 27, 111, 93, 92, 94, + 95, 96, 96, 96, 79, 95, 27, 111, 111, 79, + 111, 27, 80, 95, 93, 111, 111, 79, 30, 30, + 84, 97, 80, 111, 95, 86, 111, 80, 79, 111, + 30, 111, 111, 97, 25, 80, 111, 86, 26, 111, + 100, 25, 111, 87, 111, 26, 80, 30, 30, 84, + 97, 98, 98, 98, 86, 99, 27, 25, 100, 111, + 25, 26, 25, 27, 26, 111, 26, 25, 111, 102, + 101, 26, 87, 111, 111, 103, 111, 111, 111, 27, + 111, 111, 27, 111, 27, 111, 102, 101, 111, 27, + 111, 111, 103, 95, 104, 104, 104, 79, 95, 96, + 96, 96, 79, 25, 25, 25, 25, 26, 26, 26, + 26, 111, 111, 107, 111, 80, 106, 111, 25, 111, + 80, 111, 26, 111, 111, 27, 27, 27, 27, 111, + 107, 111, 111, 106, 95, 104, 104, 104, 79, 25, + 27, 25, 25, 26, 111, 26, 26, 25, 108, 109, + 110, 26, 111, 111, 111, 111, 80, 111, 111, 111, + + 111, 27, 111, 27, 27, 108, 109, 110, 111, 27, + 22, 22, 22, 29, 29, 29, 52, 52, 30, 30, + 30, 60, 60, 60, 83, 83, 83, 5, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111 } ; -static yyconst flex_int16_t yy_chk[495] = +static yyconst flex_int16_t yy_chk[673] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, - 4, 4, 7, 7, 7, 8, 8, 8, 9, 9, - 9, 7, 10, 10, 8, 12, 12, 12, 104, 10, - 13, 13, 13, 26, 26, 26, 27, 27, 27, 29, - 29, 84, 22, 16, 74, 16, 22, 10, 11, 11, - 11, 16, 11, 11, 60, 11, 11, 11, 11, 22, + 1, 1, 1, 1, 3, 3, 4, 4, 6, 7, + 7, 119, 6, 8, 8, 8, 8, 23, 23, 30, + 8, 9, 9, 9, 9, 9, 115, 11, 12, 14, + 6, 11, 12, 14, 14, 28, 28, 19, 8, 113, + 12, 19, 30, 9, 10, 10, 10, 10, 10, 11, + 12, 14, 14, 19, 15, 58, 16, 12, 15, 19, - 16, 12, 16, 22, 34, 17, 36, 36, 16, 58, - 58, 18, 17, 18, 36, 28, 11, 15, 15, 15, - 33, 15, 15, 17, 15, 15, 15, 15, 18, 17, - 18, 19, 21, 21, 19, 15, 20, 38, 20, 23, - 20, 39, 23, 6, 33, 15, 48, 5, 19, 21, - 21, 19, 15, 20, 38, 20, 23, 20, 39, 23, - 24, 24, 24, 48, 24, 24, 49, 24, 24, 24, - 24, 30, 30, 30, 31, 31, 31, 32, 32, 0, - 30, 35, 44, 49, 32, 35, 35, 44, 24, 37, - 37, 37, 40, 40, 40, 42, 42, 42, 0, 44, + 16, 53, 53, 18, 15, 5, 10, 18, 20, 0, + 19, 16, 20, 0, 18, 0, 15, 20, 16, 0, + 21, 15, 10, 13, 21, 18, 0, 13, 16, 24, + 20, 18, 0, 24, 20, 0, 26, 13, 26, 26, + 26, 0, 21, 13, 0, 13, 25, 25, 25, 25, + 25, 24, 27, 0, 13, 0, 27, 0, 26, 31, + 13, 17, 0, 31, 0, 17, 34, 34, 25, 34, + 0, 17, 0, 34, 27, 17, 0, 29, 29, 29, + 29, 31, 0, 17, 29, 63, 63, 63, 17, 0, + 0, 34, 17, 35, 35, 35, 35, 35, 66, 66, - 47, 47, 32, 51, 44, 35, 41, 41, 41, 0, - 41, 41, 0, 41, 41, 41, 41, 47, 47, 0, - 51, 57, 57, 57, 83, 83, 45, 89, 89, 50, - 55, 50, 70, 45, 41, 43, 43, 43, 43, 43, - 43, 43, 43, 43, 45, 46, 50, 55, 50, 70, - 45, 52, 46, 0, 52, 53, 43, 43, 43, 43, - 43, 54, 53, 46, 0, 0, 54, 67, 52, 46, - 61, 52, 53, 67, 61, 61, 73, 0, 54, 53, - 62, 62, 62, 54, 69, 67, 0, 0, 0, 69, - 67, 66, 0, 73, 61, 64, 64, 64, 66, 64, + 66, 0, 29, 32, 32, 32, 32, 32, 32, 32, + 32, 81, 81, 81, 81, 35, 37, 86, 86, 86, + 37, 38, 38, 38, 38, 38, 0, 0, 32, 33, + 33, 33, 33, 0, 33, 33, 33, 0, 37, 88, + 88, 88, 0, 38, 39, 40, 0, 0, 39, 40, + 0, 0, 41, 0, 33, 36, 41, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 39, 40, 42, 41, + 0, 43, 42, 42, 41, 43, 43, 36, 36, 36, + 36, 36, 36, 44, 45, 46, 41, 44, 45, 46, + 42, 42, 0, 43, 43, 48, 44, 50, 47, 48, - 64, 69, 64, 64, 64, 64, 69, 68, 68, 66, - 71, 71, 79, 72, 77, 66, 72, 0, 0, 0, - 77, 0, 0, 64, 68, 68, 0, 71, 71, 79, - 72, 0, 77, 72, 75, 75, 75, 77, 75, 75, - 82, 75, 75, 75, 75, 0, 78, 78, 80, 81, - 81, 80, 85, 85, 87, 86, 88, 82, 86, 0, - 0, 0, 75, 78, 78, 80, 81, 81, 80, 85, - 85, 87, 86, 88, 90, 86, 91, 90, 92, 93, - 91, 94, 92, 0, 0, 0, 0, 0, 0, 0, - 0, 90, 0, 91, 90, 92, 93, 91, 94, 92, + 49, 50, 47, 0, 49, 44, 45, 46, 47, 49, + 51, 0, 0, 44, 51, 0, 50, 48, 0, 50, + 47, 0, 49, 0, 56, 47, 49, 51, 56, 97, + 97, 97, 51, 50, 54, 54, 54, 54, 54, 55, + 0, 55, 55, 55, 51, 0, 56, 60, 60, 60, + 60, 61, 0, 0, 60, 61, 54, 64, 64, 64, + 64, 55, 65, 65, 64, 65, 99, 99, 99, 65, + 0, 0, 60, 61, 62, 62, 62, 62, 62, 62, + 62, 62, 64, 105, 105, 105, 0, 65, 68, 68, + 68, 68, 68, 69, 0, 0, 70, 69, 69, 62, - 96, 96, 96, 96, 96, 97, 97, 0, 97, 97, - 98, 98, 98, 98, 98, 99, 99, 0, 99, 99, - 100, 100, 0, 100, 100, 101, 0, 101, 101, 101, - 102, 102, 102, 102, 102, 103, 103, 0, 103, 103, - 105, 105, 0, 105, 105, 106, 106, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95 + 70, 71, 70, 73, 72, 71, 0, 73, 72, 0, + 68, 0, 0, 75, 71, 69, 69, 75, 70, 0, + 70, 72, 75, 71, 74, 73, 72, 0, 74, 76, + 77, 71, 0, 76, 77, 75, 0, 74, 72, 75, + 78, 78, 78, 78, 78, 79, 74, 0, 0, 79, + 0, 76, 77, 80, 74, 0, 0, 80, 83, 83, + 83, 83, 78, 0, 84, 83, 0, 79, 84, 0, + 87, 87, 0, 87, 89, 80, 0, 87, 89, 0, + 89, 91, 0, 83, 0, 91, 84, 85, 85, 85, + 85, 85, 85, 85, 85, 87, 89, 90, 89, 0, + 92, 90, 93, 91, 92, 0, 93, 94, 0, 92, + 90, 94, 85, 0, 0, 93, 0, 0, 0, 90, + 0, 0, 92, 0, 93, 0, 92, 90, 0, 94, + 0, 0, 93, 95, 95, 95, 95, 95, 96, 96, + 96, 96, 96, 100, 101, 102, 103, 100, 101, 102, + 103, 0, 0, 101, 0, 95, 100, 0, 109, 0, + 96, 0, 109, 0, 0, 100, 101, 102, 103, 0, + 101, 0, 0, 100, 104, 104, 104, 104, 104, 106, + 109, 107, 108, 106, 0, 107, 108, 110, 106, 107, + 108, 110, 0, 0, 0, 0, 104, 0, 0, 0, + + 0, 106, 0, 107, 108, 106, 107, 108, 0, 110, + 112, 112, 112, 114, 114, 114, 116, 116, 117, 117, + 117, 118, 118, 118, 120, 120, 120, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111 } ; /* The intent behind this definition is that it'll catch @@ -587,7 +629,7 @@ static yyconst flex_int16_t yy_chk[495] = #include #define YY_NO_UNISTD_H 1 -#line 591 "sapi/phpdbg/phpdbg_lexer.c" +#line 633 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -827,7 +869,7 @@ YY_DECL #line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 831 "sapi/phpdbg/phpdbg_lexer.c" +#line 873 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -882,13 +924,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 95 ); + while ( yy_current_state != 111 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -995,7 +1037,6 @@ YY_RULE_SETUP } YY_BREAK case 10: -/* rule 10 can match eol */ YY_RULE_SETUP #line 100 "sapi/phpdbg/dev/phpdbg_lexer.l" { @@ -1056,17 +1097,9 @@ YY_RULE_SETUP case 16: YY_RULE_SETUP #line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_UNEXPECTED; -} - YY_BREAK -case 17: -YY_RULE_SETUP -#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1070 "sapi/phpdbg/phpdbg_lexer.c" +#line 1103 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1362,7 +1395,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1391,11 +1424,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 96 ) + if ( yy_current_state >= 112 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 95); + yy_is_jam = (yy_current_state == 111); return yy_is_jam ? 0 : yy_current_state; } @@ -2231,7 +2264,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 40e64e159e3..f5d949a2075 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 136 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_list.c b/phpdbg_list.c index a1bd8c0ff53..60377142925 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -29,14 +29,18 @@ #include "phpdbg.h" #include "phpdbg_list.h" #include "phpdbg_utils.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13]) + const phpdbg_command_t phpdbg_list_commands[] = { - PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, "l"), - PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, "s"), - PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, "m"), - PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, "s"), + PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l"), + PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s"), + PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m"), + PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s"), PHPDBG_END_COMMAND }; @@ -49,12 +53,12 @@ PHPDBG_LIST(lines) /* {{{ */ switch (param->type) { case NUMERIC_PARAM: - case EMPTY_PARAM: phpdbg_list_file(phpdbg_current_file(TSRMLS_C), - param->type == EMPTY_PARAM ? 0 : (param->num < 0 ? 1 - param->num : param->num), - (param->type != EMPTY_PARAM && param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), + (param->num < 0 ? 1 - param->num : param->num), + (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC); break; + case FILE_PARAM: phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC); break; diff --git a/phpdbg_print.c b/phpdbg_print.c index ed630c200c7..c0265d60cf2 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -26,13 +26,16 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9]) + const phpdbg_command_t phpdbg_print_commands[] = { - PHPDBG_COMMAND_D_EX(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), - PHPDBG_COMMAND_D_EX(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), - PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"), - PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"), - PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"), - PHPDBG_COMMAND_D_EX(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), + PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0), + PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0), + PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"), + PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"), + PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"), + PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0), PHPDBG_END_COMMAND }; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index aed1f4a0156..3830f44a646 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -55,14 +55,13 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, "s"), PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 0), - PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), - PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "n"), + PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"), + PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"), PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, "s"), PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0), PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0), PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"), - PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, "b"), PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, "s"), @@ -376,9 +375,8 @@ PHPDBG_COMMAND(compile) /* {{{ */ PHPDBG_COMMAND(step) /* {{{ */ { switch (param->type) { - case EMPTY_PARAM: case NUMERIC_PARAM: { - if (param->type == NUMERIC_PARAM && param->num) { + if (param->num) { PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } else { PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; @@ -495,15 +493,13 @@ PHPDBG_COMMAND(leave) /* {{{ */ PHPDBG_COMMAND(frame) /* {{{ */ { - switch (param->type) { + if (!param || param->type == EMPTY_PARAM) { + phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); + } else switch (param->type) { case NUMERIC_PARAM: phpdbg_switch_frame(param->num TSRMLS_CC); break; - case EMPTY_PARAM: - phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); - break; - phpdbg_default_switch_case(); } @@ -681,11 +677,11 @@ PHPDBG_COMMAND(back) /* {{{ */ return SUCCESS; } - switch (param->type) { - case EMPTY_PARAM: + if (!param || param->type == EMPTY_PARAM) { + phpdbg_dump_backtrace(0 TSRMLS_CC); + } else switch (param->type) { case NUMERIC_PARAM: - phpdbg_dump_backtrace( - (param->type == NUMERIC_PARAM) ? param->num : 0 TSRMLS_CC); + phpdbg_dump_backtrace(param->num TSRMLS_CC); break; phpdbg_default_switch_case(); @@ -696,46 +692,42 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: { - phpdbg_writeln(SEPARATE); - phpdbg_notice("Execution Context Information"); + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln(SEPARATE); + phpdbg_notice("Execution Context Information"); #ifdef HAVE_LIBREADLINE - phpdbg_writeln("Readline\tyes"); + phpdbg_writeln("Readline\tyes"); #else - phpdbg_writeln("Readline\tno"); + phpdbg_writeln("Readline\tno"); #endif - phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); - phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); - phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); - phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); + phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); + phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); + phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); + phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); - if (PHPDBG_G(ops)) { - phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); + if (PHPDBG_G(ops)) { + phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); - if (PHPDBG_G(ops)->last_var) { - phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); - } else { - phpdbg_writeln("Variables\tNone"); - } + if (PHPDBG_G(ops)->last_var) { + phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); + } else { + phpdbg_writeln("Variables\tNone"); } + } - phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); - if (EG(in_execution)) { - phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); - } + phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); + if (EG(in_execution)) { + phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); + } - phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); - phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); - phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); - phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); + phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); - phpdbg_writeln(SEPARATE); - } break; - - phpdbg_default_switch_case(); + phpdbg_writeln(SEPARATE); } return SUCCESS; @@ -759,12 +751,11 @@ PHPDBG_COMMAND(set) /* {{{ */ PHPDBG_COMMAND(break) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: - phpdbg_set_breakpoint_file( + if (!param || param->type == EMPTY_PARAM) { + phpdbg_set_breakpoint_file( zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); - break; + } else switch (param->type) { case ADDR_PARAM: phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); break; @@ -926,25 +917,6 @@ PHPDBG_COMMAND(clear) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(quiet) /* {{{ */ -{ - switch (param->type) { - case NUMERIC_PARAM: { - if (param->num) { - PHPDBG_G(flags) |= PHPDBG_IS_QUIET; - } else { - PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; - } - phpdbg_notice("Quietness %s", - (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled"); - } break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - PHPDBG_COMMAND(list) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index e66ea16dce3..d92623d409c 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -47,7 +47,6 @@ PHPDBG_COMMAND(info); PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clear); PHPDBG_COMMAND(help); -PHPDBG_COMMAND(quiet); PHPDBG_COMMAND(shell); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); diff --git a/phpdbg_set.c b/phpdbg_set.c index 7ce67d934d0..739acd3c714 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -23,67 +23,50 @@ #include "phpdbg_set.h" #include "phpdbg_utils.h" #include "phpdbg_bp.h" +#include "phpdbg_prompt.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +#define PHPDBG_SET_COMMAND_D(f, h, a, m, l, s) \ + PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[18]) + const phpdbg_command_t phpdbg_set_commands[] = { - PHPDBG_COMMAND_D_EX(prompt, "usage: set prompt ", 'p', set_prompt, NULL, "s"), + PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt []", 'p', set_prompt, NULL, "|s"), #ifndef _WIN32 - PHPDBG_COMMAND_D_EX(color, "usage: set color ", 'c', set_color, NULL, "ss"), - PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, "b"), + PHPDBG_SET_COMMAND_D(color, "usage: set color ", 'c', set_color, NULL, "ss"), + PHPDBG_SET_COMMAND_D(colors, "usage: set colors []", 'C', set_colors, NULL, "|b"), #endif - PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, "s"), - PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, "lb"), + PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog []", 'O', set_oplog, NULL, "|s"), + PHPDBG_SET_COMMAND_D(break, "usage: set break id []", 'b', set_break, NULL, "l|b"), + PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks []", 'B', set_breaks, NULL, "|b"), + PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet []", 'q', set_quiet, NULL, "|b"), PHPDBG_END_COMMAND }; PHPDBG_SET(prompt) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: - phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); - break; - - case STR_PARAM: - phpdbg_set_prompt(param->str TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", phpdbg_get_prompt(TSRMLS_C)); + } else phpdbg_set_prompt(param->str TSRMLS_CC); + return SUCCESS; } /* }}} */ PHPDBG_SET(break) /* {{{ */ { - if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("%s", - PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); - } else switch (param->type) { - case STR_PARAM: - if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { - phpdbg_enable_breakpoints(TSRMLS_C); - } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { - phpdbg_disable_breakpoints(TSRMLS_C); - } - break; - + switch (param->type) { case NUMERIC_PARAM: { if (param->next) { - /* - if (phpdbg_argv_is(2, "on")) { - phpdbg_enable_breakpoint(param->num TSRMLS_CC); - } else if (phpdbg_argv_is(2, "off")) { - phpdbg_disable_breakpoint(param->num TSRMLS_CC); - } - */ + if (param->next->num) { + phpdbg_enable_breakpoint(param->num TSRMLS_CC); + } else phpdbg_disable_breakpoint(param->num TSRMLS_CC); } else { phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); if (brake) { phpdbg_writeln( "%s", brake->disabled ? "off" : "on"); } else { - phpdbg_error("Failed to find breakpoint #%lx", param->num); + phpdbg_error("Failed to find breakpoint #%ld", param->num); } } } break; @@ -96,6 +79,26 @@ PHPDBG_SET(break) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_SET(breaks) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", + PHPDBG_G(flags) & PHPDBG_IS_BP_ENABLED ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + phpdbg_enable_breakpoints(TSRMLS_C); + } else phpdbg_disable_breakpoints(TSRMLS_C); + } break; + + default: + phpdbg_error( + "set break used incorrectly: set break [id] "); + } + + return SUCCESS; +} /* }}} */ + #ifndef _WIN32 PHPDBG_SET(color) /* {{{ */ { @@ -141,58 +144,31 @@ usage: PHPDBG_SET(colors) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: { - phpdbg_writeln( - "%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); - goto done; - } - - case STR_PARAM: { - if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("%s", PHPDBG_G(flags) & PHPDBG_IS_COLOURED ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { PHPDBG_G(flags) |= PHPDBG_IS_COLOURED; - goto done; - } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { + } else { PHPDBG_G(flags) &= ~PHPDBG_IS_COLOURED; - goto done; } - } + } break; default: phpdbg_error( "set colors used incorrectly: set colors "); } -done: return SUCCESS; } /* }}} */ #endif PHPDBG_SET(oplog) /* {{{ */ { - switch (param->type) { - case EMPTY_PARAM: - phpdbg_notice( - "Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled"); - break; - - case NUMERIC_PARAM: switch (param->num) { - case 1: - phpdbg_error( - "An output file must be provided to enable oplog"); - break; - - case 0: { - if (PHPDBG_G(oplog)) { - phpdbg_notice("Disabling oplog"); - fclose( - PHPDBG_G(oplog)); - } else { - phpdbg_error("Oplog is not enabled!"); - } - } break; - } break; - + if (!param || param->type == EMPTY_PARAM) { + phpdbg_notice("Oplog %s", PHPDBG_G(oplog) ? "enabled" : "disabled"); + } else switch (param->type) { case STR_PARAM: { /* open oplog */ FILE *old = PHPDBG_G(oplog); @@ -216,3 +192,19 @@ PHPDBG_SET(oplog) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_SET(quiet) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Quietness %s", + PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_QUIET; + } else PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } break; + } + + return SUCCESS; +} /* }}} */ + diff --git a/phpdbg_set.h b/phpdbg_set.h index ddc3876f5dc..4d90aac5b2d 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -32,6 +32,8 @@ PHPDBG_SET(colors); #endif PHPDBG_SET(oplog); PHPDBG_SET(break); +PHPDBG_SET(breaks); +PHPDBG_SET(quiet); extern const phpdbg_command_t phpdbg_set_commands[]; From 5db16dd9892d7aa4e5be5f049141051da35542d9 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 14:44:16 +0000 Subject: [PATCH 061/137] better-ness, I think --- dev/phpdbg_lexer.l | 81 +++------ dev/phpdbg_parser.y | 96 +++++----- phpdbg_break.c | 16 +- phpdbg_break.h | 1 - phpdbg_help.c | 9 +- phpdbg_lexer.c | 420 +++++++++++++++----------------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 248 +++++++++++++------------- phpdbg_parser.h | 29 ++- phpdbg_prompt.c | 3 + 10 files changed, 361 insertions(+), 544 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index e20f9dcc933..52d1d448026 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -21,88 +21,61 @@ %option reentrant noyywrap never-interactive nounistd %option bison-bridge -C_TRUE ?i:"true" -C_YES ?i:"yes" -C_ON ?i:"on" -C_ENABLED ?i:"enabled" -C_FALSE ?i:"false" -C_NO ?i:"no" -C_OFF ?i:"off" -C_DISABLED ?i:"disabled" -C_EVAL ?i:"eval" -C_SHELL ?i:"shell" -C_IF ?i:"if" +T_TRUE ?i:"true" +T_YES ?i:"yes" +T_ON ?i:"on" +T_ENABLED ?i:"enabled" +T_FALSE ?i:"false" +T_NO ?i:"no" +T_OFF ?i:"off" +T_DISABLED ?i:"disabled" +T_EVAL ?i:"eval" +T_SHELL ?i:"shell" +T_IF ?i:"if" WS [ \r\n\t]+ DIGITS [0-9\.]+ -ID [^ \r\n\t]+ -NSID [\\\\]?{ID} -METHOD {NSID}+::{ID} -NUMERIC_METHOD {METHOD}[#]{DIGITS} -NUMERIC_FUNCTION {NSID}[#]{DIGITS} -FILE [^ :\r\n\t]+:[0-9]+ +ID [^ \r\n\t:#]+ OPLINE 0x[a-fA-F0-9]+ LITERAL \"(\\.|[^\\"])*\" INPUT [^\n]+ %% { - {C_EVAL} { + [#]{1} { return T_POUND; } + [:]{2} { return T_DCOLON; } + [:]{1} { return T_COLON; } + + {T_EVAL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); - return C_EVAL; + return T_EVAL; } - {C_SHELL} { + {T_SHELL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); - return C_SHELL; + return T_SHELL; } - {C_IF} { + {T_IF} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); - return C_IF; + return T_IF; } - {C_YES}|{C_ON}|{C_ENABLED}|{C_TRUE} { + {T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; - return C_TRUTHY; + return T_TRUTHY; } - {C_NO}|{C_OFF}|{C_DISABLED}|{C_FALSE} { + {T_NO}|{T_OFF}|{T_DISABLED}|{T_FALSE} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; - return C_FALSY; + return T_FALSY; } {DIGITS} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } - {NUMERIC_METHOD} { - phpdbg_init_param(yylval, NUMERIC_METHOD_PARAM); - yylval->method.class = "class"; - yylval->method.name = "func"; - yylval->num = 0; - return T_METHOD; - } - {NUMERIC_FUNCTION} { - phpdbg_init_param(yylval, NUMERIC_FUNCTION_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - yylval->num = 0; - return T_ID; - } - {METHOD} { - phpdbg_init_param(yylval, METHOD_PARAM); - yylval->method.class = "class"; - yylval->method.name = "func"; - return T_METHOD; - } - {FILE} { - phpdbg_init_param(yylval, FILE_PARAM); - yylval->file.name = strndup(yytext, yyleng); - yylval->file.line = 0; - return T_FILE; - } {OPLINE} { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); @@ -114,7 +87,7 @@ INPUT [^\n]+ yylval->len = yyleng; return T_LITERAL; } - {NSID} { + {ID} { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); yylval->len = yyleng; diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 90e79f8b5a3..842f6a25d84 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -43,7 +43,6 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { typedef void* yyscan_t; #endif } -%expect 1 %output "sapi/phpdbg/phpdbg_parser.c" %defines "sapi/phpdbg/phpdbg_parser.h" @@ -52,27 +51,27 @@ typedef void* yyscan_t; %parse-param { phpdbg_param_t *stack } %parse-param { yyscan_t scanner } -%token C_TRUTHY "truthy (true, on, yes or enabled)" -%token C_FALSY "falsy (false, off, no or disabled)" -%token C_STRING "string (some input, perhaps)" -%token C_EVAL "eval" -%token C_SHELL "shell" -%token C_IF "if (condition)" +%token T_EVAL "eval" +%token T_SHELL "shell" +%token T_IF "if (condition)" +%token T_TRUTHY "truthy (true, on, yes or enabled)" +%token T_FALSY "falsy (false, off, no or disabled)" +%token T_STRING "string (some input, perhaps)" +%token T_COLON ": (colon)" +%token T_DCOLON ":: (double colon)" +%token T_POUND "# (pound sign)" %token T_DIGITS "digits (numbers)" %token T_LITERAL "literal (string)" -%token T_METHOD "method" -%token T_NUMERIC_METHOD "method opline address" -%token T_NUMERIC_FUNCTION "function opline address" %token T_OPLINE "opline" -%token T_FILE "file" %token T_ID "identifier (command or function name)" %token T_INPUT "input (input string or data)" %token T_UNEXPECTED "input" %% input - : handler + : parameters + | /* nothing */ ; parameters @@ -80,41 +79,50 @@ parameters | parameters parameter { phpdbg_stack_push(stack, &$2); } ; -params - : parameters - | /* empty */ - ; - -normal - : T_ID { phpdbg_stack_push(stack, &$1); } - | normal T_ID { phpdbg_stack_push(stack, &$2); } - ; - -special - : C_EVAL T_INPUT { $$ = $2; $$.type = EVAL_PARAM; } - | C_SHELL T_INPUT { $$ = $2; $$.type = SHELL_PARAM; } - ; - -command - : normal - | special { phpdbg_stack_push(stack, &$1); } - ; - parameter - : T_DIGITS { $$ = $1; } - | T_FILE { $$ = $1; } - | T_METHOD { $$ = $1; } - | T_NUMERIC_METHOD { $$ = $1; } - | T_NUMERIC_FUNCTION { $$ = $1; } + : T_ID T_COLON T_DIGITS { + $$.type = FILE_PARAM; + $$.file.name = $1.str; + $$.file.line = $3.num; + } + | T_ID T_DCOLON T_ID { + $$.type = METHOD_PARAM; + $$.method.class = $1.str; + $$.method.name = $3.str; + } + | T_ID T_DCOLON T_ID T_POUND T_DIGITS { + $$.type = NUMERIC_METHOD_PARAM; + $$.method.class = $1.str; + $$.method.name = $3.str; + $$.num = $5.num; + } + | T_ID T_POUND T_DIGITS { + $$.type = NUMERIC_FUNCTION_PARAM; + $$.str = $1.str; + $$.len = $1.len; + $$.num = $3.num; + } + | T_IF T_INPUT { + $$.type = COND_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + | T_EVAL T_INPUT { + $$.type = EVAL_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } + | T_SHELL T_INPUT { + $$.type = SHELL_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } | T_OPLINE { $$ = $1; } - | T_ID { $$ = $1; } | T_LITERAL { $$ = $1; } - | C_TRUTHY { $$ = $1; } - | C_FALSY { $$ = $1; } - | C_IF T_INPUT { $$ = $2; $$.type = COND_PARAM; } + | T_TRUTHY { $$ = $1; } + | T_FALSY { $$ = $1; } + | T_DIGITS { $$ = $1; } + | T_ID { $$ = $1; } ; -handler - : command params - ; %% diff --git a/phpdbg_break.c b/phpdbg_break.c index fdf4e198b5e..92b4e2eb5f2 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -39,8 +39,7 @@ const phpdbg_command_t phpdbg_break_commands[] = { PHPDBG_BREAK_COMMAND_D(func, "specify breakpoint by global function name", 'f', break_func, NULL, "s"), PHPDBG_BREAK_COMMAND_D(method, "specify breakpoint by class::method", 'm', break_method, NULL, "m"), PHPDBG_BREAK_COMMAND_D(address, "specify breakpoint by address", 'a', break_address, NULL, "a"), - PHPDBG_BREAK_COMMAND_D(op, "specify breakpoint by opcode", 'O', break_op, NULL, "s"), - PHPDBG_BREAK_COMMAND_D(on, "specify breakpoint by condition", 'o', break_on, NULL, "c"), + PHPDBG_BREAK_COMMAND_D(op, "specify breakpoint by opcode", 'o', break_op, NULL, "s"), PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), PHPDBG_BREAK_COMMAND_D(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "n"), PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), @@ -98,19 +97,6 @@ PHPDBG_BREAK(address) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_BREAK(on) /* {{{ */ -{ - switch (param->type) { - case STR_PARAM: - phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - PHPDBG_BREAK(at) /* {{{ */ { phpdbg_set_breakpoint_at(param TSRMLS_CC); diff --git a/phpdbg_break.h b/phpdbg_break.h index 38f1298c932..d356fa0d0ed 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -35,7 +35,6 @@ PHPDBG_BREAK(method); PHPDBG_BREAK(address); PHPDBG_BREAK(at); PHPDBG_BREAK(op); -PHPDBG_BREAK(on); PHPDBG_BREAK(lineno); PHPDBG_BREAK(del); diff --git a/phpdbg_help.c b/phpdbg_help.c index c5da19b9881..115cf2dd312 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -507,15 +507,12 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **method** **m** specify breakpoint by class::method" CR " **address** **a** specify breakpoint by address" CR " **op** **O** specify breakpoint by opcode" CR -" **on** **o** specify breakpoint by condition" CR " **at** **A** specify breakpoint by location and condition" CR " **del** **d** delete breakpoint by breakpoint identifier number" CR CR "The syntax of the target argument is dependent on the target type and in the case of address, " "file, func, line and method targets the target keyword or alias is optional and can be omitted." CR CR -"**Break on** takes a string argument which must be a valid PHP expression." CR CR - "**Break at** takes two arguments. The first is any valid target as per the file, lineno, func " "and address types. The second is a valid PHP expression which will trigger the break in " "execution, if evaluated as true in a boolean context at the specified target." CR CR @@ -562,8 +559,8 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P b a test.php#3" CR " Break at the opline #3 of test.php" CR CR -" $P break on $cnt > 10" CR -" $P b o $cnt > 10" CR +" $P break if $cnt > 10" CR +" $P b if $cnt > 10" CR " Break when the condition ($cnt > 10) evaluates to true" CR CR " $P break at phpdbg::isGreat if $opt == 'S'" CR @@ -573,7 +570,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Break at every opcode on line 20 of test.php when the condition evaluates to true" CR CR " $P break op ZEND_ADD" CR -" $P b O ZEND_ADD" CR +" $P b o ZEND_ADD" CR " Break on any occurence of the opcode ZEND_ADD" CR CR " $P break del 2" CR diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 4515b6d822e..76ef43136ec 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 16 -#define YY_END_OF_BUFFER 17 +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,21 +358,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[112] = +static yyconst flex_int16_t yy_accept[73] = { 0, - 0, 0, 0, 0, 17, 13, 15, 13, 6, 6, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 14, 14, 13, 13, 13, 13, 15, 13, 0, - 12, 13, 13, 13, 6, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 3, 5, 13, 4, 13, 13, - 13, 14, 14, 8, 10, 13, 12, 0, 8, 13, - 12, 13, 10, 13, 13, 13, 11, 8, 13, 13, - 13, 13, 5, 13, 13, 4, 9, 9, 9, 9, - 13, 8, 9, 9, 9, 9, 9, 13, 13, 13, - 1, 13, 13, 4, 9, 8, 9, 8, 9, 13, - - 13, 5, 2, 7, 7, 13, 13, 13, 4, 5, - 0 + 0, 0, 0, 0, 16, 12, 14, 12, 1, 9, + 9, 3, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 13, 12, 14, 12, 0, 11, 12, 9, + 12, 2, 12, 12, 12, 12, 6, 8, 12, 7, + 12, 12, 12, 13, 13, 11, 0, 10, 12, 12, + 12, 12, 8, 12, 12, 7, 12, 12, 4, 12, + 12, 7, 12, 12, 8, 5, 12, 12, 12, 7, + 8, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -409,201 +404,95 @@ static yyconst flex_int32_t yy_ec[256] = static yyconst flex_int32_t yy_meta[45] = { 0, - 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[121] = +static yyconst flex_int16_t yy_base[78] = { 0, - 0, 0, 43, 45, 106, 44, 48, 52, 57, 80, - 63, 64, 119, 65, 90, 92, 157, 99, 73, 104, - 116, 0, 56, 125, 142, 132, 148, 74, 176, 56, - 155, 202, 228, 165, 189, 251, 212, 217, 240, 241, - 248, 264, 267, 279, 280, 281, 294, 291, 296, 293, - 306, 0, 100, 330, 335, 320, 628, 93, 0, 346, - 347, 373, 180, 356, 361, 193, 0, 384, 389, 392, - 397, 400, 399, 420, 409, 425, 426, 436, 441, 449, - 206, 0, 457, 460, 486, 212, 469, 234, 470, 493, - 477, 496, 498, 503, 529, 534, 324, 0, 361, 539, - - 540, 541, 542, 570, 378, 575, 577, 578, 554, 583, - 628, 610, 79, 613, 66, 616, 618, 621, 51, 624 + 0, 0, 43, 45, 135, 0, 47, 49, 187, 49, + 53, 96, 45, 44, 54, 51, 47, 53, 54, 50, + 59, 0, 72, 0, 75, 89, 77, 0, 97, 101, + 110, 187, 73, 87, 91, 92, 0, 0, 96, 0, + 99, 90, 104, 0, 130, 187, 100, 0, 119, 123, + 118, 115, 0, 126, 131, 0, 135, 130, 0, 135, + 132, 0, 133, 141, 0, 0, 142, 144, 145, 0, + 0, 187, 175, 64, 178, 181, 183 } ; -static yyconst flex_int16_t yy_def[121] = +static yyconst flex_int16_t yy_def[78] = { 0, - 111, 1, 112, 112, 111, 113, 111, 114, 113, 113, - 115, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 116, 116, 113, 113, 115, 113, 111, 114, 117, - 113, 114, 118, 114, 113, 113, 115, 115, 115, 115, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 116, 116, 113, 115, 119, 111, 117, 32, 118, - 115, 118, 62, 120, 118, 32, 36, 115, 113, 113, - 113, 113, 113, 113, 113, 113, 119, 119, 119, 119, - 62, 62, 120, 119, 120, 85, 120, 62, 113, 113, - 113, 113, 113, 113, 119, 119, 85, 85, 85, 113, - - 113, 113, 113, 119, 85, 113, 113, 113, 113, 113, - 0, 111, 111, 111, 111, 111, 111, 111, 111, 111 + 72, 1, 73, 73, 72, 74, 72, 75, 72, 74, + 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 76, 76, 74, 72, 75, 77, 74, 75, 74, + 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 76, 76, 72, 77, 31, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 0, 72, 72, 72, 72, 72 } ; -static yyconst flex_int16_t yy_nxt[673] = +static yyconst flex_int16_t yy_nxt[232] = { 0, - 6, 7, 7, 8, 6, 9, 10, 9, 11, 6, - 6, 6, 12, 13, 14, 6, 15, 6, 16, 17, - 6, 18, 19, 6, 6, 20, 21, 6, 6, 12, - 13, 14, 6, 15, 6, 16, 17, 6, 18, 19, - 6, 6, 6, 20, 23, 7, 23, 7, 25, 28, - 28, 77, 26, 30, 30, 31, 32, 53, 28, 57, - 33, 25, 35, 35, 35, 26, 37, 38, 25, 25, - 27, 39, 26, 26, 44, 28, 28, 25, 34, 24, - 41, 26, 58, 27, 25, 35, 35, 35, 26, 40, - 27, 27, 44, 50, 25, 111, 25, 41, 26, 27, + 6, 7, 7, 8, 9, 10, 11, 10, 12, 6, + 6, 6, 13, 14, 15, 6, 16, 6, 17, 18, + 6, 19, 20, 6, 6, 21, 6, 6, 6, 13, + 14, 15, 6, 16, 6, 17, 18, 6, 19, 20, + 6, 6, 6, 21, 23, 7, 23, 7, 25, 25, + 27, 27, 28, 27, 30, 30, 30, 27, 30, 30, + 30, 33, 34, 36, 24, 37, 38, 39, 35, 41, + 42, 40, 43, 45, 25, 29, 25, 25, 33, 34, + 46, 36, 37, 38, 39, 35, 41, 42, 40, 43, + 27, 27, 28, 27, 49, 31, 50, 27, 27, 72, - 26, 53, 28, 25, 45, 111, 27, 26, 25, 111, - 50, 46, 26, 111, 49, 111, 27, 51, 27, 111, - 25, 45, 36, 25, 26, 27, 111, 26, 46, 25, - 27, 49, 111, 26, 51, 111, 38, 42, 55, 55, - 56, 111, 27, 43, 111, 27, 25, 54, 54, 54, - 26, 27, 25, 111, 42, 111, 26, 111, 40, 25, - 43, 25, 111, 26, 111, 26, 30, 111, 27, 32, - 111, 47, 111, 33, 27, 48, 111, 30, 30, 31, - 32, 27, 111, 27, 33, 60, 63, 63, 47, 111, - 111, 66, 48, 25, 35, 35, 35, 26, 29, 29, + 51, 27, 72, 47, 32, 27, 30, 30, 30, 52, + 53, 49, 54, 55, 50, 29, 48, 48, 51, 48, + 48, 48, 48, 48, 48, 56, 52, 53, 57, 54, + 55, 45, 25, 58, 72, 59, 60, 48, 48, 48, + 48, 48, 56, 61, 62, 63, 57, 64, 65, 66, + 67, 58, 59, 60, 68, 69, 70, 71, 72, 72, + 61, 62, 72, 63, 64, 65, 66, 67, 72, 72, + 72, 68, 69, 70, 71, 22, 22, 22, 26, 26, + 26, 44, 44, 27, 27, 27, 5, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 29, 111, 34, 30, 30, 31, 32, 59, 59, 59, - 33, 60, 60, 60, 64, 27, 38, 83, 83, 83, - 39, 38, 68, 68, 68, 39, 111, 111, 34, 30, - 30, 61, 62, 111, 63, 63, 64, 111, 40, 60, - 60, 60, 111, 40, 38, 38, 111, 111, 56, 39, - 111, 111, 25, 111, 65, 25, 26, 67, 67, 26, - 67, 67, 67, 67, 67, 67, 40, 40, 25, 69, - 111, 25, 26, 70, 27, 26, 71, 27, 67, 67, - 67, 67, 67, 25, 25, 25, 69, 26, 26, 26, - 27, 70, 111, 27, 71, 25, 72, 25, 25, 26, - - 25, 26, 26, 111, 26, 27, 27, 27, 73, 74, - 25, 111, 111, 72, 26, 111, 75, 27, 111, 27, - 27, 111, 27, 111, 78, 73, 74, 76, 79, 105, - 105, 105, 27, 75, 25, 54, 54, 54, 26, 38, - 111, 55, 55, 39, 76, 111, 80, 30, 30, 61, - 62, 38, 111, 111, 81, 39, 27, 30, 30, 84, - 85, 40, 30, 111, 86, 62, 83, 83, 83, 81, - 111, 111, 65, 40, 30, 30, 61, 62, 82, 82, - 82, 81, 87, 105, 105, 105, 111, 88, 38, 68, - 68, 68, 39, 25, 111, 111, 25, 26, 89, 65, - - 26, 25, 90, 25, 25, 26, 111, 26, 26, 111, - 40, 111, 111, 25, 91, 27, 89, 26, 27, 111, - 90, 92, 94, 27, 25, 27, 27, 111, 26, 25, - 95, 91, 111, 26, 79, 27, 111, 93, 92, 94, - 95, 96, 96, 96, 79, 95, 27, 111, 111, 79, - 111, 27, 80, 95, 93, 111, 111, 79, 30, 30, - 84, 97, 80, 111, 95, 86, 111, 80, 79, 111, - 30, 111, 111, 97, 25, 80, 111, 86, 26, 111, - 100, 25, 111, 87, 111, 26, 80, 30, 30, 84, - 97, 98, 98, 98, 86, 99, 27, 25, 100, 111, - - 25, 26, 25, 27, 26, 111, 26, 25, 111, 102, - 101, 26, 87, 111, 111, 103, 111, 111, 111, 27, - 111, 111, 27, 111, 27, 111, 102, 101, 111, 27, - 111, 111, 103, 95, 104, 104, 104, 79, 95, 96, - 96, 96, 79, 25, 25, 25, 25, 26, 26, 26, - 26, 111, 111, 107, 111, 80, 106, 111, 25, 111, - 80, 111, 26, 111, 111, 27, 27, 27, 27, 111, - 107, 111, 111, 106, 95, 104, 104, 104, 79, 25, - 27, 25, 25, 26, 111, 26, 26, 25, 108, 109, - 110, 26, 111, 111, 111, 111, 80, 111, 111, 111, - - 111, 27, 111, 27, 27, 108, 109, 110, 111, 27, - 22, 22, 22, 29, 29, 29, 52, 52, 30, 30, - 30, 60, 60, 60, 83, 83, 83, 5, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111 + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72 } ; -static yyconst flex_int16_t yy_chk[673] = +static yyconst flex_int16_t yy_chk[232] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 4, 4, 6, 7, - 7, 119, 6, 8, 8, 8, 8, 23, 23, 30, - 8, 9, 9, 9, 9, 9, 115, 11, 12, 14, - 6, 11, 12, 14, 14, 28, 28, 19, 8, 113, - 12, 19, 30, 9, 10, 10, 10, 10, 10, 11, - 12, 14, 14, 19, 15, 58, 16, 12, 15, 19, + 1, 1, 1, 1, 3, 3, 4, 4, 7, 7, + 8, 8, 8, 8, 10, 10, 10, 8, 11, 11, + 11, 13, 14, 15, 74, 16, 17, 18, 14, 19, + 20, 18, 21, 23, 23, 8, 25, 25, 13, 14, + 27, 15, 16, 17, 18, 14, 19, 20, 18, 21, + 26, 26, 26, 26, 33, 11, 34, 26, 29, 29, - 16, 53, 53, 18, 15, 5, 10, 18, 20, 0, - 19, 16, 20, 0, 18, 0, 15, 20, 16, 0, - 21, 15, 10, 13, 21, 18, 0, 13, 16, 24, - 20, 18, 0, 24, 20, 0, 26, 13, 26, 26, - 26, 0, 21, 13, 0, 13, 25, 25, 25, 25, - 25, 24, 27, 0, 13, 0, 27, 0, 26, 31, - 13, 17, 0, 31, 0, 17, 34, 34, 25, 34, - 0, 17, 0, 34, 27, 17, 0, 29, 29, 29, - 29, 31, 0, 17, 29, 63, 63, 63, 17, 0, - 0, 34, 17, 35, 35, 35, 35, 35, 66, 66, + 35, 29, 47, 27, 12, 29, 30, 30, 30, 36, + 39, 33, 41, 42, 34, 26, 31, 31, 35, 31, + 31, 31, 31, 31, 31, 43, 36, 39, 49, 41, + 42, 45, 45, 50, 5, 51, 52, 31, 31, 31, + 31, 31, 43, 54, 55, 57, 49, 58, 60, 61, + 63, 50, 51, 52, 64, 67, 68, 69, 0, 0, + 54, 55, 0, 57, 58, 60, 61, 63, 0, 0, + 0, 64, 67, 68, 69, 73, 73, 73, 75, 75, + 75, 76, 76, 77, 77, 77, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 66, 0, 29, 32, 32, 32, 32, 32, 32, 32, - 32, 81, 81, 81, 81, 35, 37, 86, 86, 86, - 37, 38, 38, 38, 38, 38, 0, 0, 32, 33, - 33, 33, 33, 0, 33, 33, 33, 0, 37, 88, - 88, 88, 0, 38, 39, 40, 0, 0, 39, 40, - 0, 0, 41, 0, 33, 36, 41, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 39, 40, 42, 41, - 0, 43, 42, 42, 41, 43, 43, 36, 36, 36, - 36, 36, 36, 44, 45, 46, 41, 44, 45, 46, - 42, 42, 0, 43, 43, 48, 44, 50, 47, 48, - - 49, 50, 47, 0, 49, 44, 45, 46, 47, 49, - 51, 0, 0, 44, 51, 0, 50, 48, 0, 50, - 47, 0, 49, 0, 56, 47, 49, 51, 56, 97, - 97, 97, 51, 50, 54, 54, 54, 54, 54, 55, - 0, 55, 55, 55, 51, 0, 56, 60, 60, 60, - 60, 61, 0, 0, 60, 61, 54, 64, 64, 64, - 64, 55, 65, 65, 64, 65, 99, 99, 99, 65, - 0, 0, 60, 61, 62, 62, 62, 62, 62, 62, - 62, 62, 64, 105, 105, 105, 0, 65, 68, 68, - 68, 68, 68, 69, 0, 0, 70, 69, 69, 62, - - 70, 71, 70, 73, 72, 71, 0, 73, 72, 0, - 68, 0, 0, 75, 71, 69, 69, 75, 70, 0, - 70, 72, 75, 71, 74, 73, 72, 0, 74, 76, - 77, 71, 0, 76, 77, 75, 0, 74, 72, 75, - 78, 78, 78, 78, 78, 79, 74, 0, 0, 79, - 0, 76, 77, 80, 74, 0, 0, 80, 83, 83, - 83, 83, 78, 0, 84, 83, 0, 79, 84, 0, - 87, 87, 0, 87, 89, 80, 0, 87, 89, 0, - 89, 91, 0, 83, 0, 91, 84, 85, 85, 85, - 85, 85, 85, 85, 85, 87, 89, 90, 89, 0, - - 92, 90, 93, 91, 92, 0, 93, 94, 0, 92, - 90, 94, 85, 0, 0, 93, 0, 0, 0, 90, - 0, 0, 92, 0, 93, 0, 92, 90, 0, 94, - 0, 0, 93, 95, 95, 95, 95, 95, 96, 96, - 96, 96, 96, 100, 101, 102, 103, 100, 101, 102, - 103, 0, 0, 101, 0, 95, 100, 0, 109, 0, - 96, 0, 109, 0, 0, 100, 101, 102, 103, 0, - 101, 0, 0, 100, 104, 104, 104, 104, 104, 106, - 109, 107, 108, 106, 0, 107, 108, 110, 106, 107, - 108, 110, 0, 0, 0, 0, 104, 0, 0, 0, - - 0, 106, 0, 107, 108, 106, 107, 108, 0, 110, - 112, 112, 112, 114, 114, 114, 116, 116, 117, 117, - 117, 118, 118, 118, 120, 120, 120, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111 + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72 } ; /* The intent behind this definition is that it'll catch @@ -629,7 +518,7 @@ static yyconst flex_int16_t yy_chk[673] = #include #define YY_NO_UNISTD_H 1 -#line 633 "sapi/phpdbg/phpdbg_lexer.c" +#line 522 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -867,9 +756,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 873 "sapi/phpdbg/phpdbg_lexer.c" +#line 762 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -924,13 +813,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 112 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 111 ); + while ( yy_current_state != 72 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -952,113 +841,86 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 50 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return C_EVAL; - } +#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_POUND; } YY_BREAK case 2: YY_RULE_SETUP -#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return C_SHELL; - } +#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_DCOLON; } YY_BREAK case 3: YY_RULE_SETUP -#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return C_IF; - } +#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_COLON; } YY_BREAK case 4: YY_RULE_SETUP -#line 65 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 49 "sapi/phpdbg/dev/phpdbg_lexer.l" { - phpdbg_init_param(yylval, NUMERIC_PARAM); - yylval->num = 1; - return C_TRUTHY; + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_EVAL; } YY_BREAK case 5: YY_RULE_SETUP -#line 70 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" { - phpdbg_init_param(yylval, NUMERIC_PARAM); - yylval->num = 0; - return C_FALSY; + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_SHELL; } YY_BREAK case 6: YY_RULE_SETUP -#line 75 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 59 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_IF; + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 1; + return T_TRUTHY; + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 69 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = 0; + return T_FALSY; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 74 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 7: -YY_RULE_SETUP -#line 80 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, NUMERIC_METHOD_PARAM); - yylval->method.class = "class"; - yylval->method.name = "func"; - yylval->num = 0; - return T_METHOD; - } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 87 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, NUMERIC_FUNCTION_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - yylval->num = 0; - return T_ID; - } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 94 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, METHOD_PARAM); - yylval->method.class = "class"; - yylval->method.name = "func"; - return T_METHOD; - } - YY_BREAK case 10: YY_RULE_SETUP -#line 100 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, FILE_PARAM); - yylval->file.name = strndup(yytext, yyleng); - yylval->file.line = 0; - return T_FILE; - } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 79 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_OPLINE; } YY_BREAK -case 12: -/* rule 12 can match eol */ +case 11: +/* rule 11 can match eol */ YY_RULE_SETUP -#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1066,9 +928,9 @@ YY_RULE_SETUP return T_LITERAL; } YY_BREAK -case 13: +case 12: YY_RULE_SETUP -#line 117 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1077,9 +939,9 @@ YY_RULE_SETUP } YY_BREAK -case 14: +case 13: YY_RULE_SETUP -#line 124 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 97 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1088,18 +950,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 15: -/* rule 15 can match eol */ +case 14: +/* rule 14 can match eol */ YY_RULE_SETUP -#line 131 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 16: +case 15: YY_RULE_SETUP -#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1103 "sapi/phpdbg/phpdbg_lexer.c" +#line 965 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1395,7 +1257,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 112 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1424,11 +1286,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 112 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 111); + yy_is_jam = (yy_current_state == 72); return yy_is_jam ? 0 : yy_current_state; } @@ -2264,7 +2126,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index f5d949a2075..6a799c655d3 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 132 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 37bd4d80bc3..099daa30e58 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -147,22 +147,21 @@ typedef void* yyscan_t; /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - C_TRUTHY = 258, - C_FALSY = 259, - C_STRING = 260, - C_EVAL = 261, - C_SHELL = 262, - C_IF = 263, - T_DIGITS = 264, - T_LITERAL = 265, - T_METHOD = 266, - T_NUMERIC_METHOD = 267, - T_NUMERIC_FUNCTION = 268, + T_EVAL = 258, + T_SHELL = 259, + T_IF = 260, + T_TRUTHY = 261, + T_FALSY = 262, + T_STRING = 263, + T_COLON = 264, + T_DCOLON = 265, + T_POUND = 266, + T_DIGITS = 267, + T_LITERAL = 268, T_OPLINE = 269, - T_FILE = 270, - T_ID = 271, - T_INPUT = 272, - T_UNEXPECTED = 273 + T_ID = 270, + T_INPUT = 271, + T_UNEXPECTED = 272 }; #endif @@ -180,7 +179,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 184 "sapi/phpdbg/phpdbg_parser.c" +#line 183 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -397,22 +396,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 11 +#define YYFINAL 19 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 24 +#define YYLAST 22 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 19 +#define YYNTOKENS 18 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 9 +#define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 24 +#define YYNRULES 18 /* YYNRULES -- Number of states. */ -#define YYNSTATES 29 +#define YYNSTATES 26 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 273 +#define YYMAXUTOK 272 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -447,7 +446,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18 + 15, 16, 17 }; #if YYDEBUG @@ -455,28 +454,25 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 7, 10, 12, 13, 15, 18, - 21, 24, 26, 28, 30, 32, 34, 36, 38, 40, - 42, 44, 46, 48, 51 + 0, 0, 3, 5, 6, 8, 11, 15, 19, 25, + 29, 31, 33, 35, 37, 39, 41, 44, 47 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 20, 0, -1, 27, -1, 26, -1, 21, 26, -1, - 21, -1, -1, 16, -1, 23, 16, -1, 6, 17, - -1, 7, 17, -1, 23, -1, 24, -1, 9, -1, - 15, -1, 11, -1, 12, -1, 13, -1, 14, -1, - 16, -1, 10, -1, 3, -1, 4, -1, 8, 17, - -1, 25, 22, -1 + 19, 0, -1, 20, -1, -1, 21, -1, 20, 21, + -1, 15, 9, 12, -1, 15, 10, 15, -1, 15, + 10, 15, 11, 12, -1, 15, 11, 12, -1, 14, + -1, 13, -1, 6, -1, 7, -1, 12, -1, 15, + -1, 5, 16, -1, 3, 16, -1, 4, 16, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 75, 75, 79, 80, 84, 85, 89, 90, 94, - 95, 99, 100, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 118 + 0, 73, 73, 74, 78, 79, 83, 88, 93, 99, + 104, 105, 106, 107, 108, 109, 110, 111, 112 }; #endif @@ -485,15 +481,15 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "\"truthy (true, on, yes or enabled)\"", + "$end", "error", "$undefined", "\"eval\"", "\"shell\"", + "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", - "\"string (some input, perhaps)\"", "\"eval\"", "\"shell\"", - "\"if (condition)\"", "\"digits (numbers)\"", "\"literal (string)\"", - "\"method\"", "\"method opline address\"", "\"function opline address\"", - "\"opline\"", "\"file\"", "\"identifier (command or function name)\"", + "\"string (some input, perhaps)\"", "\": (colon)\"", + "\":: (double colon)\"", "\"# (pound sign)\"", "\"digits (numbers)\"", + "\"literal (string)\"", "\"opline\"", + "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", - "parameters", "params", "normal", "special", "command", "parameter", - "handler", 0 + "parameters", "parameter", 0 }; #endif @@ -503,24 +499,22 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273 + 265, 266, 267, 268, 269, 270, 271, 272 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 19, 20, 21, 21, 22, 22, 23, 23, 24, - 24, 25, 25, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27 + 0, 18, 19, 19, 20, 20, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 1, 2, 1, 0, 1, 2, 2, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2 + 0, 2, 1, 0, 1, 2, 3, 3, 5, 3, + 1, 1, 1, 1, 1, 1, 2, 2, 2 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -528,31 +522,31 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 0, 0, 0, 7, 0, 11, 12, 6, 2, 9, - 10, 1, 8, 21, 22, 0, 13, 20, 15, 16, - 17, 18, 14, 19, 5, 24, 3, 23, 4 + 3, 0, 0, 0, 12, 13, 14, 11, 10, 15, + 0, 2, 4, 17, 18, 16, 0, 0, 0, 1, + 5, 6, 7, 9, 0, 8 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 4, 24, 25, 5, 6, 7, 26, 8 + -1, 10, 11, 12 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -16 +#define YYPACT_NINF -9 static const yytype_int8 yypact[] = { - 8, -15, -14, -16, 4, 0, -16, -3, -16, -16, - -16, -16, -16, -16, -16, 1, -16, -16, -16, -16, - -16, -16, -16, -16, -3, -16, -16, -16, -16 + -3, -8, -2, -1, -9, -9, -9, -9, -9, -4, + 13, -3, -9, -9, -9, -9, 4, 2, 6, -9, + -9, -9, 8, -9, 9, -9 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -16, -16, -16, -16, -16, -16, -16, -7, -16 + -9, -9, -9, 11 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -561,31 +555,31 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 13, 14, 9, 10, 11, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 1, 2, 12, 28, 27, 0, - 0, 0, 0, 0, 3 + 1, 2, 3, 4, 5, 16, 17, 18, 13, 6, + 7, 8, 9, 19, 14, 15, 21, 22, 23, 24, + 0, 25, 20 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-16)) + ((yystate) == (-9)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 17, 17, 0, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 6, 7, 16, 24, 17, -1, - -1, -1, -1, -1, 16 + 3, 4, 5, 6, 7, 9, 10, 11, 16, 12, + 13, 14, 15, 0, 16, 16, 12, 15, 12, 11, + -1, 12, 11 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 6, 7, 16, 20, 23, 24, 25, 27, 17, - 17, 0, 16, 3, 4, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 21, 22, 26, 17, 26 + 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, + 19, 20, 21, 16, 16, 16, 9, 10, 11, 0, + 21, 12, 15, 12, 11, 12 }; #define yyerrok (yyerrstatus = 0) @@ -1431,136 +1425,132 @@ yyreduce: YY_REDUCE_PRINT (yyn); switch (yyn) { - case 3: + case 4: /* Line 1806 of yacc.c */ -#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 78 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; - case 4: + case 5: /* Line 1806 of yacc.c */ -#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; + case 6: + +/* Line 1806 of yacc.c */ +#line 83 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = FILE_PARAM; + (yyval).file.name = (yyvsp[(1) - (3)]).str; + (yyval).file.line = (yyvsp[(3) - (3)]).num; + } + break; + case 7: /* Line 1806 of yacc.c */ -#line 89 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } +#line 88 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (3)]).str; + (yyval).method.name = (yyvsp[(3) - (3)]).str; + } break; case 8: /* Line 1806 of yacc.c */ -#line 90 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } +#line 93 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = NUMERIC_METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (5)]).str; + (yyval).method.name = (yyvsp[(3) - (5)]).str; + (yyval).num = (yyvsp[(5) - (5)]).num; + } break; case 9: /* Line 1806 of yacc.c */ -#line 94 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } +#line 99 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FUNCTION_PARAM; + (yyval).str = (yyvsp[(1) - (3)]).str; + (yyval).num = (yyvsp[(3) - (3)]).num; + } break; case 10: -/* Line 1806 of yacc.c */ -#line 95 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } - break; - - case 12: - -/* Line 1806 of yacc.c */ -#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } - break; - - case 13: - /* Line 1806 of yacc.c */ #line 104 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 14: + case 11: /* Line 1806 of yacc.c */ #line 105 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 15: + case 12: /* Line 1806 of yacc.c */ #line 106 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 16: + case 13: /* Line 1806 of yacc.c */ #line 107 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 17: + case 14: /* Line 1806 of yacc.c */ #line 108 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 18: + case 15: /* Line 1806 of yacc.c */ #line 109 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 19: + case 16: /* Line 1806 of yacc.c */ #line 110 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 20: - -/* Line 1806 of yacc.c */ -#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 21: - -/* Line 1806 of yacc.c */ -#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 22: - -/* Line 1806 of yacc.c */ -#line 113 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 23: - -/* Line 1806 of yacc.c */ -#line 114 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } break; + case 17: + +/* Line 1806 of yacc.c */ +#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } + break; + + case 18: + +/* Line 1806 of yacc.c */ +#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } + break; + /* Line 1806 of yacc.c */ -#line 1564 "sapi/phpdbg/phpdbg_parser.c" +#line 1554 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1791,6 +1781,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 120 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 115 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 5c0ac4819e7..d0ba3b13604 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -52,22 +52,21 @@ typedef void* yyscan_t; /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - C_TRUTHY = 258, - C_FALSY = 259, - C_STRING = 260, - C_EVAL = 261, - C_SHELL = 262, - C_IF = 263, - T_DIGITS = 264, - T_LITERAL = 265, - T_METHOD = 266, - T_NUMERIC_METHOD = 267, - T_NUMERIC_FUNCTION = 268, + T_EVAL = 258, + T_SHELL = 259, + T_IF = 260, + T_TRUTHY = 261, + T_FALSY = 262, + T_STRING = 263, + T_COLON = 264, + T_DCOLON = 265, + T_POUND = 266, + T_DIGITS = 267, + T_LITERAL = 268, T_OPLINE = 269, - T_FILE = 270, - T_ID = 271, - T_INPUT = 272, - T_UNEXPECTED = 273 + T_ID = 270, + T_INPUT = 271, + T_UNEXPECTED = 272 }; #endif diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 3830f44a646..24d24956f9d 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -778,6 +778,9 @@ PHPDBG_COMMAND(break) /* {{{ */ case FILE_PARAM: phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break; + case COND_PARAM: + phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); + break; case STR_PARAM: phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); break; From 78e8690dee8af62d9fa1fbd547f88585ba89b33e Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 15:00:55 +0000 Subject: [PATCH 062/137] conditional breakpoints working again --- phpdbg_bp.c | 59 +++++++++++++---------------------------------------- 1 file changed, 14 insertions(+), 45 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index cacc48f13f9..53415a31488 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -762,55 +762,24 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ { - /* - if (input->argc > 3 && phpdbg_argv_is(2, "if")) { - phpdbg_breakcond_t new_break; - phpdbg_param_t new_param; - - zend_ulong expr_hash = 0L; - size_t expr_len; - const char *join = strstr(input->string, "if"); - const char *expr = (join) + sizeof("if"); - - expr_len = strlen(expr); - expr = phpdbg_trim(expr, expr_len, &expr_len); - expr_hash = zend_inline_hash_func(expr, expr_len); - - { - size_t sparam_len = 0L; - char *sparam = input->string; - - sparam[ - strstr(input->string, " ") - input->string] = 0; - sparam_len = strlen(sparam); - - switch (phpdbg_parse_param(sparam, sparam_len, &new_param TSRMLS_CC)) { - case EMPTY_PARAM: - case NUMERIC_PARAM: - phpdbg_clear_param( - &new_param TSRMLS_CC); - goto usage; - - default: { } break; - } - - expr_hash += phpdbg_hash_param(&new_param TSRMLS_CC); - } - - if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], expr_hash)) { + phpdbg_breakcond_t new_break; + phpdbg_param_t *condition; + zend_ulong hash = 0L; + + if (param->next) { + condition = param->next; + hash = zend_inline_hash_func(condition->str, condition->len); + + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) { phpdbg_create_conditional_break( - &new_break, &new_param, expr, expr_len, expr_hash TSRMLS_CC); + &new_break, param, + condition->str, condition->len, hash TSRMLS_CC); } else { phpdbg_notice( - "Conditional break %s exists at the specified location", expr); - } - - phpdbg_clear_param(&new_param TSRMLS_CC); - } else { -usage: - phpdbg_error("usage: break at if "); + "Conditional break %s exists at the specified location", condition->str); + } } - */ + } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ From fde1e44d6254a24e272067673091e67bf4451c5f Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 16:18:46 +0000 Subject: [PATCH 063/137] trim breaking commands --- dev/phpdbg_lexer.l | 17 ++- dev/phpdbg_parser.y | 13 ++- phpdbg.c | 23 +--- phpdbg_break.c | 108 +----------------- phpdbg_break.h | 5 - phpdbg_cmd.c | 10 ++ phpdbg_cmd.h | 2 + phpdbg_help.c | 43 +++---- phpdbg_lexer.c | 269 ++++++++++++++++++++++++-------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 217 ++++++++++++++++++++--------------- phpdbg_parser.h | 20 ++-- phpdbg_prompt.c | 3 + 13 files changed, 346 insertions(+), 386 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 52d1d448026..ae8eeb78319 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -35,8 +35,9 @@ T_IF ?i:"if" WS [ \r\n\t]+ DIGITS [0-9\.]+ -ID [^ \r\n\t:#]+ -OPLINE 0x[a-fA-F0-9]+ +ID [^ \r\n\t:#~]+ +ADDR 0x[a-fA-F0-9]+ +OPCODE ZEND_([A-Z])+ LITERAL \"(\\.|[^\\"])*\" INPUT [^\n]+ %% @@ -45,7 +46,7 @@ INPUT [^\n]+ [#]{1} { return T_POUND; } [:]{2} { return T_DCOLON; } [:]{1} { return T_COLON; } - + [~]{1} { return T_SQUIGGLE; } {T_EVAL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -76,10 +77,16 @@ INPUT [^\n]+ yylval->num = atoi(yytext); return T_DIGITS; } - {OPLINE} { + {ADDR} { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); - return T_OPLINE; + return T_ADDR; + } + {OPCODE} { + phpdbg_init_param(yylval, OP_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_OPCODE; } {LITERAL} { phpdbg_init_param(yylval, STR_PARAM); diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 842f6a25d84..a811ba870db 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -57,13 +57,15 @@ typedef void* yyscan_t; %token T_TRUTHY "truthy (true, on, yes or enabled)" %token T_FALSY "falsy (false, off, no or disabled)" %token T_STRING "string (some input, perhaps)" +%token T_SQUIGGLE "~ (squiggle)" %token T_COLON ": (colon)" %token T_DCOLON ":: (double colon)" %token T_POUND "# (pound sign)" %token T_DIGITS "digits (numbers)" %token T_LITERAL "literal (string)" -%token T_OPLINE "opline" +%token T_ADDR "address" +%token T_OPCODE "opcode" %token T_ID "identifier (command or function name)" %token T_INPUT "input (input string or data)" %token T_UNEXPECTED "input" @@ -80,7 +82,11 @@ parameters ; parameter - : T_ID T_COLON T_DIGITS { + : T_SQUIGGLE T_DIGITS { + $$.type = OPLINE_PARAM; + $$.num = $2.num; + } + | T_ID T_COLON T_DIGITS { $$.type = FILE_PARAM; $$.file.name = $1.str; $$.file.line = $3.num; @@ -117,7 +123,8 @@ parameter $$.str = $2.str; $$.len = $2.len; } - | T_OPLINE { $$ = $1; } + | T_OPCODE { $$ = $1; } + | T_ADDR { $$ = $1; } | T_LITERAL { $$ = $1; } | T_TRUTHY { $$ = $1; } | T_FALSY { $$ = $1; } diff --git a/phpdbg.c b/phpdbg.c index 0b748f0e85e..b08b09ff989 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -268,28 +268,7 @@ static PHP_FUNCTION(phpdbg_break) } phpdbg_parse_param(expr, expr_len, ¶m TSRMLS_CC); - - switch (type) { - case METHOD_PARAM: - phpdbg_do_break_method(¶m TSRMLS_CC); - break; - - case FILE_PARAM: - phpdbg_do_break_file(¶m TSRMLS_CC); - break; - - case NUMERIC_PARAM: - phpdbg_do_break_lineno(¶m TSRMLS_CC); - break; - - case STR_PARAM: - phpdbg_do_break_func(¶m TSRMLS_CC); - break; - - default: zend_error( - E_WARNING, "unrecognized parameter type %ld", type); - } - + phpdbg_do_break(¶m TSRMLS_CC); phpdbg_clear_param(¶m TSRMLS_CC); } else if (EG(current_execute_data) && EG(active_op_array)) { diff --git a/phpdbg_break.c b/phpdbg_break.c index 92b4e2eb5f2..b83bdffe343 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -35,64 +35,15 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_BREAK_COMMAND_D(file, "specify breakpoint by file:line", 'F', break_file, NULL, "f"), - PHPDBG_BREAK_COMMAND_D(func, "specify breakpoint by global function name", 'f', break_func, NULL, "s"), - PHPDBG_BREAK_COMMAND_D(method, "specify breakpoint by class::method", 'm', break_method, NULL, "m"), - PHPDBG_BREAK_COMMAND_D(address, "specify breakpoint by address", 'a', break_address, NULL, "a"), - PHPDBG_BREAK_COMMAND_D(op, "specify breakpoint by opcode", 'o', break_op, NULL, "s"), - PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), - PHPDBG_BREAK_COMMAND_D(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, "n"), - PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), + PHPDBG_BREAK_COMMAND_D(address, "specify breakpoint by address", 'a', break_address, NULL, "f"), + PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), + PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), PHPDBG_END_COMMAND }; -PHPDBG_BREAK(file) /* {{{ */ -{ - switch (param->type) { - case FILE_PARAM: - phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - -PHPDBG_BREAK(method) /* {{{ */ -{ - switch (param->type) { - case METHOD_PARAM: - phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - PHPDBG_BREAK(address) /* {{{ */ { - switch (param->type) { - case ADDR_PARAM: - phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC); - break; - - case NUMERIC_METHOD_PARAM: - phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC); - break; - - case NUMERIC_FUNCTION_PARAM: - phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC); - break; - - case FILE_PARAM: - phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } + phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -104,58 +55,9 @@ PHPDBG_BREAK(at) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_BREAK(lineno) /* {{{ */ -{ - switch (param->type) { - case NUMERIC_PARAM: { - if (PHPDBG_G(exec)) { - phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC); - } else { - phpdbg_error("Execution context not set!"); - } - } break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - -PHPDBG_BREAK(func) /* {{{ */ -{ - switch (param->type) { - case STR_PARAM: - phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - -PHPDBG_BREAK(op) /* {{{ */ -{ - switch (param->type) { - case STR_PARAM: - phpdbg_set_breakpoint_opcode(param->str, param->len TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } - - return SUCCESS; -} /* }}} */ - PHPDBG_BREAK(del) /* {{{ */ { - switch (param->type) { - case NUMERIC_PARAM: { - phpdbg_delete_breakpoint(param->num TSRMLS_CC); - } break; - - phpdbg_default_switch_case(); - } + phpdbg_delete_breakpoint(param->num TSRMLS_CC); return SUCCESS; } /* }}} */ diff --git a/phpdbg_break.h b/phpdbg_break.h index d356fa0d0ed..50d855026c9 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -29,13 +29,8 @@ /** * Printer Forward Declarations */ -PHPDBG_BREAK(file); -PHPDBG_BREAK(func); -PHPDBG_BREAK(method); PHPDBG_BREAK(address); PHPDBG_BREAK(at); -PHPDBG_BREAK(op); -PHPDBG_BREAK(lineno); PHPDBG_BREAK(del); extern const phpdbg_command_t phpdbg_break_commands[]; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 4e6ef048b82..3974edb8d10 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -442,6 +442,14 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) fprintf(stderr, "%s COND_PARAM(%s=%lu)\n", msg, param->str, param->len); break; + case OP_PARAM: + fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); + break; + + case OPLINE_PARAM: + fprintf(stderr, "%s OPLINE_PARAM(%ld)\n", msg, param->num); + break; + default: { /* not yet */ } @@ -571,6 +579,8 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param case 'a': verify_arg("address", top, ADDR_PARAM); break; case 'f': verify_arg("file:line", top, FILE_PARAM); break; case 'c': verify_arg("condition", top, COND_PARAM); break; + case 'o': verify_arg("opcode", top, OP_PARAM); break; + case 'O': verify_arg("opline", top, OPLINE_PARAM); break; case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; case '*': { /* do nothing */ } break; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 2c0ecb4540f..d6cd19dfc10 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -43,6 +43,8 @@ typedef enum { EVAL_PARAM, SHELL_PARAM, COND_PARAM, + OP_PARAM, + OPLINE_PARAM, ORIG_PARAM } phpdbg_param_type; diff --git a/phpdbg_help.c b/phpdbg_help.c index 115cf2dd312..ae37f9b720b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -501,63 +501,48 @@ phpdbg_help_text_t phpdbg_help_text[] = { "types:" CR CR " **Target** **Alias** **Purpose**" CR -" **file** **F** specify breakpoint by file:line" CR -" **lineno** **l** specify breakpoint by line of currently executing file" CR -" **func** **f** specify breakpoint by global function name" CR -" **method** **m** specify breakpoint by class::method" CR " **address** **a** specify breakpoint by address" CR -" **op** **O** specify breakpoint by opcode" CR " **at** **A** specify breakpoint by location and condition" CR " **del** **d** delete breakpoint by breakpoint identifier number" CR CR -"The syntax of the target argument is dependent on the target type and in the case of address, " -"file, func, line and method targets the target keyword or alias is optional and can be omitted." CR CR - -"**Break at** takes two arguments. The first is any valid target as per the file, lineno, func " -"and address types. The second is a valid PHP expression which will trigger the break in " +"**Break at** takes two arguments. The first is any valid target. The second " +"is a valid PHP expression which will trigger the break in " "execution, if evaluated as true in a boolean context at the specified target." CR CR "Note that breakpoints can also be disabled and re-enabled by the **set break** command." CR CR "**Examples**" CR CR -" $P break file test.php:100" CR -" $P b F test.php:100" CR +" $P break test.php:100" CR " $P b test.php:100" CR " Break execution at line 100 of test.php" CR CR -" $P break lineno 200" CR -" $P b l 200" CR +" $P break 200" CR " $P b 200" CR " Break execution at line 200 of the currently PHP script file" CR CR -" $P break func \\\\mynamespace\\\\my_function" CR -" $P b f \\\\mynamespace\\\\my_function" CR +" $P break \\\\mynamespace\\\\my_function" CR " $P b \\\\mynamespace\\\\my_function" CR " Break execution on entry to \\\\mynamespace\\\\my_function" CR CR -" $P break method classX::method" CR -" $P b m classX::method" CR +" $P break classX::method" CR " $P b classX::method" CR " Break execution on entry to classX::method" CR CR -" $P break address 0x7ff68f570e08" CR -" $P b a 0x7ff68f570e08" CR +" $P break 0x7ff68f570e08" CR " $P b 0x7ff68f570e08" CR " Break at the opline at the address 0x7ff68f570e08" CR CR -" $P break address my_function#14" CR -" $P b a my_function#14" CR +" $P break my_function#14" CR " $P b my_function#14" CR " Break at the opline #14 of the function my_function" CR CR -" $P break address \\\\my\\\\class::method#2" CR -" $P b a \\\\my\\\\class::method#2" CR +" $P break \\\\my\\\\class::method#2" CR " $P b \\\\my\\\\class::method#2" CR " Break at the opline #2 of the method \\\\my\\\\class::method" CR CR -" $P break address test.php#3" CR -" $P b a test.php#3" CR -" Break at the opline #3 of test.php" CR CR +" $P break address test.php:3" CR +" $P b a test.php:3" CR +" Break at the 3rd opline in test.php" CR CR " $P break if $cnt > 10" CR " $P b if $cnt > 10" CR @@ -569,8 +554,8 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P break at test.php:20 if !isset($x)" CR " Break at every opcode on line 20 of test.php when the condition evaluates to true" CR CR -" $P break op ZEND_ADD" CR -" $P b o ZEND_ADD" CR +" $P break ZEND_ADD" CR +" $P b ZEND_ADD" CR " Break on any occurence of the opcode ZEND_ADD" CR CR " $P break del 2" CR diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 76ef43136ec..590d0825d7a 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,16 +358,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[73] = +static yyconst flex_int16_t yy_accept[80] = { 0, - 0, 0, 0, 0, 16, 12, 14, 12, 1, 9, - 9, 3, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 13, 12, 14, 12, 0, 11, 12, 9, - 12, 2, 12, 12, 12, 12, 6, 8, 12, 7, - 12, 12, 12, 13, 13, 11, 0, 10, 12, 12, - 12, 12, 8, 12, 12, 7, 12, 12, 4, 12, - 12, 7, 12, 12, 8, 5, 12, 12, 12, 7, - 8, 0 + 0, 0, 0, 0, 18, 14, 16, 14, 1, 10, + 10, 3, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 4, 15, 15, 14, 16, 14, 0, 13, + 14, 10, 14, 2, 14, 14, 14, 14, 7, 9, + 14, 8, 14, 14, 14, 14, 15, 15, 13, 0, + 11, 14, 14, 14, 14, 9, 14, 14, 8, 14, + 14, 14, 5, 14, 14, 8, 14, 14, 14, 9, + 6, 14, 14, 14, 12, 14, 8, 9, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -379,13 +379,13 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 6, 1, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, - 1, 16, 17, 1, 1, 18, 1, 19, 20, 1, - 1, 21, 22, 23, 24, 25, 1, 1, 26, 1, - 1, 27, 1, 1, 1, 1, 28, 29, 12, 30, + 16, 17, 18, 16, 16, 19, 16, 20, 21, 16, + 16, 22, 23, 24, 25, 26, 16, 16, 27, 28, + 1, 29, 1, 1, 30, 1, 31, 32, 33, 34, - 31, 32, 1, 33, 34, 1, 1, 35, 1, 36, - 37, 1, 1, 38, 39, 40, 41, 42, 1, 43, - 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 35, 36, 1, 37, 38, 1, 1, 39, 1, 40, + 41, 1, 1, 42, 43, 44, 45, 46, 1, 47, + 48, 1, 1, 1, 1, 49, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -402,97 +402,113 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[45] = +static yyconst flex_int32_t yy_meta[50] = { 0, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 2 } ; -static yyconst flex_int16_t yy_base[78] = +static yyconst flex_int16_t yy_base[85] = { 0, - 0, 0, 43, 45, 135, 0, 47, 49, 187, 49, - 53, 96, 45, 44, 54, 51, 47, 53, 54, 50, - 59, 0, 72, 0, 75, 89, 77, 0, 97, 101, - 110, 187, 73, 87, 91, 92, 0, 0, 96, 0, - 99, 90, 104, 0, 130, 187, 100, 0, 119, 123, - 118, 115, 0, 126, 131, 0, 135, 130, 0, 135, - 132, 0, 133, 141, 0, 0, 142, 144, 145, 0, - 0, 187, 175, 64, 178, 181, 183 + 0, 0, 48, 50, 139, 0, 52, 54, 246, 54, + 58, 129, 49, 48, 59, 55, 51, 60, 56, 55, + 64, 123, 246, 0, 79, 0, 82, 104, 72, 0, + 109, 109, 152, 246, 79, 79, 88, 85, 0, 0, + 105, 0, 107, 98, 102, 110, 0, 124, 246, 92, + 0, 118, 118, 112, 109, 0, 115, 121, 0, 73, + 125, 129, 0, 126, 136, 0, 49, 150, 156, 0, + 0, 182, 176, 199, 0, 200, 0, 0, 246, 234, + 70, 237, 240, 242 } ; -static yyconst flex_int16_t yy_def[78] = +static yyconst flex_int16_t yy_def[85] = { 0, - 72, 1, 73, 73, 72, 74, 72, 75, 72, 74, - 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 76, 76, 74, 72, 75, 77, 74, 75, 74, - 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 76, 76, 72, 77, 31, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 0, 72, 72, 72, 72, 72 + 79, 1, 80, 80, 79, 81, 79, 82, 79, 81, + 81, 79, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 79, 83, 83, 81, 79, 82, 84, 81, + 82, 81, 81, 79, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 83, 83, 79, 84, + 33, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 72, 81, 81, 81, 0, 79, + 79, 79, 79, 79 } ; -static yyconst flex_int16_t yy_nxt[232] = +static yyconst flex_int16_t yy_nxt[296] = { 0, 6, 7, 7, 8, 9, 10, 11, 10, 12, 6, - 6, 6, 13, 14, 15, 6, 16, 6, 17, 18, - 6, 19, 20, 6, 6, 21, 6, 6, 6, 13, - 14, 15, 6, 16, 6, 17, 18, 6, 19, 20, - 6, 6, 6, 21, 23, 7, 23, 7, 25, 25, - 27, 27, 28, 27, 30, 30, 30, 27, 30, 30, - 30, 33, 34, 36, 24, 37, 38, 39, 35, 41, - 42, 40, 43, 45, 25, 29, 25, 25, 33, 34, - 46, 36, 37, 38, 39, 35, 41, 42, 40, 43, - 27, 27, 28, 27, 49, 31, 50, 27, 27, 72, + 6, 6, 13, 14, 15, 6, 6, 16, 6, 17, + 18, 6, 19, 20, 6, 6, 21, 22, 6, 6, + 6, 6, 6, 13, 14, 15, 6, 16, 6, 17, + 18, 6, 19, 20, 6, 6, 6, 21, 23, 25, + 7, 25, 7, 27, 27, 29, 29, 30, 29, 32, + 32, 32, 29, 32, 32, 32, 35, 36, 38, 39, + 26, 40, 43, 37, 41, 49, 44, 45, 72, 42, + 48, 27, 31, 27, 27, 67, 35, 36, 53, 38, + 39, 40, 43, 37, 79, 41, 44, 54, 45, 42, - 51, 27, 72, 47, 32, 27, 30, 30, 30, 52, - 53, 49, 54, 55, 50, 29, 48, 48, 51, 48, - 48, 48, 48, 48, 48, 56, 52, 53, 57, 54, - 55, 45, 25, 58, 72, 59, 60, 48, 48, 48, - 48, 48, 56, 61, 62, 63, 57, 64, 65, 66, - 67, 58, 59, 60, 68, 69, 70, 71, 72, 72, - 61, 62, 72, 63, 64, 65, 66, 67, 72, 72, - 72, 68, 69, 70, 71, 22, 22, 22, 26, 26, - 26, 44, 44, 27, 27, 27, 5, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 50, 52, 29, 55, 33, 29, 29, 30, 29, 53, + 29, 79, 29, 29, 32, 32, 32, 29, 54, 56, + 57, 52, 58, 55, 59, 48, 27, 61, 62, 60, + 63, 64, 31, 65, 66, 68, 46, 34, 79, 70, + 56, 57, 58, 79, 59, 79, 79, 69, 61, 62, + 63, 64, 29, 65, 71, 66, 68, 29, 51, 51, + 70, 51, 51, 51, 51, 51, 51, 69, 73, 74, + 79, 79, 79, 79, 71, 79, 79, 79, 79, 79, + 79, 79, 51, 51, 51, 51, 51, 51, 73, 76, + 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 76, 77, 78, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 77, 78, 24, 24, 24, 28, 28, 28, + 47, 47, 29, 29, 29, 5, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79 - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72 } ; -static yyconst flex_int16_t yy_chk[232] = +static yyconst flex_int16_t yy_chk[296] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 4, 4, 7, 7, - 8, 8, 8, 8, 10, 10, 10, 8, 11, 11, - 11, 13, 14, 15, 74, 16, 17, 18, 14, 19, - 20, 18, 21, 23, 23, 8, 25, 25, 13, 14, - 27, 15, 16, 17, 18, 14, 19, 20, 18, 21, - 26, 26, 26, 26, 33, 11, 34, 26, 29, 29, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 4, 4, 7, 7, 8, 8, 8, 8, 10, + 10, 10, 8, 11, 11, 11, 13, 14, 15, 16, + 81, 17, 19, 14, 18, 29, 20, 21, 67, 18, + 25, 25, 8, 27, 27, 60, 13, 14, 36, 15, + 16, 17, 19, 14, 50, 18, 20, 37, 21, 18, - 35, 29, 47, 27, 12, 29, 30, 30, 30, 36, - 39, 33, 41, 42, 34, 26, 31, 31, 35, 31, - 31, 31, 31, 31, 31, 43, 36, 39, 49, 41, - 42, 45, 45, 50, 5, 51, 52, 31, 31, 31, - 31, 31, 43, 54, 55, 57, 49, 58, 60, 61, - 63, 50, 51, 52, 64, 67, 68, 69, 0, 0, - 54, 55, 0, 57, 58, 60, 61, 63, 0, 0, - 0, 64, 67, 68, 69, 73, 73, 73, 75, 75, - 75, 76, 76, 77, 77, 77, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 29, 35, 8, 38, 11, 28, 28, 28, 28, 36, + 31, 31, 28, 31, 32, 32, 32, 31, 37, 41, + 43, 35, 44, 38, 45, 48, 48, 52, 53, 46, + 54, 55, 28, 57, 58, 61, 22, 12, 5, 64, + 41, 43, 44, 0, 45, 0, 0, 62, 52, 53, + 54, 55, 28, 57, 65, 58, 61, 31, 33, 33, + 64, 33, 33, 33, 33, 33, 33, 62, 68, 69, + 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, + 0, 0, 33, 33, 33, 33, 33, 33, 68, 73, + 69, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72 + 73, 74, 76, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 74, 76, 80, 80, 80, 82, 82, 82, + 83, 83, 84, 84, 84, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79 + } ; /* The intent behind this definition is that it'll catch @@ -518,7 +534,7 @@ static yyconst flex_int16_t yy_chk[232] = #include #define YY_NO_UNISTD_H 1 -#line 522 "sapi/phpdbg/phpdbg_lexer.c" +#line 538 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -756,9 +772,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 43 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 762 "sapi/phpdbg/phpdbg_lexer.c" +#line 778 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -813,13 +829,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 80 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 72 ); + while ( yy_current_state != 79 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -841,86 +857,101 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_POUND; } YY_BREAK case 2: YY_RULE_SETUP -#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_DCOLON; } YY_BREAK case 3: YY_RULE_SETUP -#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_COLON; } YY_BREAK case 4: YY_RULE_SETUP #line 49 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_SQUIGGLE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 50 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 59 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 65 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP -#line 69 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 70 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 74 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 75 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 79 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 80 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); - return T_OPLINE; + return T_ADDR; } YY_BREAK -case 11: -/* rule 11 can match eol */ +case 12: YY_RULE_SETUP -#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 85 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ + phpdbg_init_param(yylval, OP_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_OPCODE; + } + YY_BREAK +case 13: +/* rule 13 can match eol */ +YY_RULE_SETUP +#line 91 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -928,9 +959,9 @@ YY_RULE_SETUP return T_LITERAL; } YY_BREAK -case 12: +case 14: YY_RULE_SETUP -#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 97 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -939,9 +970,9 @@ YY_RULE_SETUP } YY_BREAK -case 13: +case 15: YY_RULE_SETUP -#line 97 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -950,18 +981,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 14: -/* rule 14 can match eol */ +case 16: +/* rule 16 can match eol */ YY_RULE_SETUP -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 15: +case 17: YY_RULE_SETUP -#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 965 "sapi/phpdbg/phpdbg_lexer.c" +#line 996 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1257,7 +1288,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 80 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1286,11 +1317,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 80 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 72); + yy_is_jam = (yy_current_state == 79); return yy_is_jam ? 0 : yy_current_state; } @@ -2126,7 +2157,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 6a799c655d3..0395393613c 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 105 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 099daa30e58..c252c7ab9d7 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -153,15 +153,17 @@ typedef void* yyscan_t; T_TRUTHY = 261, T_FALSY = 262, T_STRING = 263, - T_COLON = 264, - T_DCOLON = 265, - T_POUND = 266, - T_DIGITS = 267, - T_LITERAL = 268, - T_OPLINE = 269, - T_ID = 270, - T_INPUT = 271, - T_UNEXPECTED = 272 + T_SQUIGGLE = 264, + T_COLON = 265, + T_DCOLON = 266, + T_POUND = 267, + T_DIGITS = 268, + T_LITERAL = 269, + T_ADDR = 270, + T_OPCODE = 271, + T_ID = 272, + T_INPUT = 273, + T_UNEXPECTED = 274 }; #endif @@ -179,7 +181,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 183 "sapi/phpdbg/phpdbg_parser.c" +#line 185 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -396,22 +398,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 19 +#define YYFINAL 22 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 22 +#define YYLAST 25 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 18 +#define YYNTOKENS 20 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 18 +#define YYNRULES 20 /* YYNRULES -- Number of states. */ -#define YYNSTATES 26 +#define YYNSTATES 29 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 272 +#define YYMAXUTOK 274 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -446,7 +448,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17 + 15, 16, 17, 18, 19 }; #if YYDEBUG @@ -454,25 +456,28 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 6, 8, 11, 15, 19, 25, - 29, 31, 33, 35, 37, 39, 41, 44, 47 + 0, 0, 3, 5, 6, 8, 11, 14, 18, 22, + 28, 32, 35, 38, 41, 43, 45, 47, 49, 51, + 53 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 19, 0, -1, 20, -1, -1, 21, -1, 20, 21, - -1, 15, 9, 12, -1, 15, 10, 15, -1, 15, - 10, 15, 11, 12, -1, 15, 11, 12, -1, 14, - -1, 13, -1, 6, -1, 7, -1, 12, -1, 15, - -1, 5, 16, -1, 3, 16, -1, 4, 16, -1 + 21, 0, -1, 22, -1, -1, 23, -1, 22, 23, + -1, 9, 13, -1, 17, 10, 13, -1, 17, 11, + 17, -1, 17, 11, 17, 12, 13, -1, 17, 12, + 13, -1, 5, 18, -1, 3, 18, -1, 4, 18, + -1, 16, -1, 15, -1, 14, -1, 6, -1, 7, + -1, 13, -1, 17, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 73, 73, 74, 78, 79, 83, 88, 93, 99, - 104, 105, 106, 107, 108, 109, 110, 111, 112 + 0, 75, 75, 76, 80, 81, 85, 89, 94, 99, + 105, 111, 116, 121, 126, 127, 128, 129, 130, 131, + 132 }; #endif @@ -484,9 +489,9 @@ static const char *const yytname[] = "$end", "error", "$undefined", "\"eval\"", "\"shell\"", "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", - "\"string (some input, perhaps)\"", "\": (colon)\"", + "\"string (some input, perhaps)\"", "\"~ (squiggle)\"", "\": (colon)\"", "\":: (double colon)\"", "\"# (pound sign)\"", "\"digits (numbers)\"", - "\"literal (string)\"", "\"opline\"", + "\"literal (string)\"", "\"address\"", "\"opcode\"", "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", "parameters", "parameter", 0 @@ -499,22 +504,24 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272 + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 18, 19, 19, 20, 20, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21 + 0, 20, 21, 21, 22, 22, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 1, 2, 3, 3, 5, 3, - 1, 1, 1, 1, 1, 1, 2, 2, 2 + 0, 2, 1, 0, 1, 2, 2, 3, 3, 5, + 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -522,31 +529,31 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 0, 12, 13, 14, 11, 10, 15, - 0, 2, 4, 17, 18, 16, 0, 0, 0, 1, - 5, 6, 7, 9, 0, 8 + 3, 0, 0, 0, 17, 18, 0, 19, 16, 15, + 14, 20, 0, 2, 4, 12, 13, 11, 6, 0, + 0, 0, 1, 5, 7, 8, 10, 0, 9 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 10, 11, 12 + -1, 12, 13, 14 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -9 +#define YYPACT_NINF -14 static const yytype_int8 yypact[] = { - -3, -8, -2, -1, -9, -9, -9, -9, -9, -4, - 13, -3, -9, -9, -9, -9, 4, 2, 6, -9, - -9, -9, 8, -9, 9, -9 + -3, -13, -11, -10, -14, -14, -4, -14, -14, -14, + -14, 5, 18, -3, -14, -14, -14, -14, -14, 6, + 3, 8, -14, -14, -14, 10, -14, 11, -14 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -9, -9, -9, 11 + -14, -14, -14, 12 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -555,31 +562,31 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 1, 2, 3, 4, 5, 16, 17, 18, 13, 6, - 7, 8, 9, 19, 14, 15, 21, 22, 23, 24, - 0, 25, 20 + 1, 2, 3, 4, 5, 15, 6, 16, 17, 18, + 7, 8, 9, 10, 11, 19, 20, 21, 22, 24, + 25, 26, 27, 0, 28, 23 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-9)) + ((yystate) == (-14)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 5, 6, 7, 9, 10, 11, 16, 12, - 13, 14, 15, 0, 16, 16, 12, 15, 12, 11, - -1, 12, 11 + 3, 4, 5, 6, 7, 18, 9, 18, 18, 13, + 13, 14, 15, 16, 17, 10, 11, 12, 0, 13, + 17, 13, 12, -1, 13, 13 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, - 19, 20, 21, 16, 16, 16, 9, 10, 11, 0, - 21, 12, 15, 12, 11, 12 + 0, 3, 4, 5, 6, 7, 9, 13, 14, 15, + 16, 17, 21, 22, 23, 18, 18, 18, 13, 10, + 11, 12, 0, 23, 13, 17, 13, 12, 13 }; #define yyerrok (yyerrstatus = 0) @@ -1428,21 +1435,31 @@ yyreduce: case 4: /* Line 1806 of yacc.c */ -#line 78 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 5: /* Line 1806 of yacc.c */ -#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 81 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 6: /* Line 1806 of yacc.c */ -#line 83 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 85 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = OPLINE_PARAM; + (yyval).num = (yyvsp[(2) - (2)]).num; + } + break; + + case 7: + +/* Line 1806 of yacc.c */ +#line 89 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (3)]).str; @@ -1450,10 +1467,10 @@ yyreduce: } break; - case 7: + case 8: /* Line 1806 of yacc.c */ -#line 88 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 94 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1461,96 +1478,116 @@ yyreduce: } break; - case 8: - -/* Line 1806 of yacc.c */ -#line 93 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = NUMERIC_METHOD_PARAM; - (yyval).method.class = (yyvsp[(1) - (5)]).str; - (yyval).method.name = (yyvsp[(3) - (5)]).str; - (yyval).num = (yyvsp[(5) - (5)]).num; - } - break; - case 9: /* Line 1806 of yacc.c */ #line 99 "sapi/phpdbg/dev/phpdbg_parser.y" { - (yyval).type = NUMERIC_FUNCTION_PARAM; - (yyval).str = (yyvsp[(1) - (3)]).str; - (yyval).num = (yyvsp[(3) - (3)]).num; + (yyval).type = NUMERIC_METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (5)]).str; + (yyval).method.name = (yyvsp[(3) - (5)]).str; + (yyval).num = (yyvsp[(5) - (5)]).num; } break; case 10: /* Line 1806 of yacc.c */ -#line 104 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } +#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FUNCTION_PARAM; + (yyval).str = (yyvsp[(1) - (3)]).str; + (yyval).len = (yyvsp[(1) - (3)]).len; + (yyval).num = (yyvsp[(3) - (3)]).num; + } break; case 11: /* Line 1806 of yacc.c */ -#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } +#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = COND_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } break; case 12: /* Line 1806 of yacc.c */ -#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } +#line 116 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = EVAL_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } break; case 13: /* Line 1806 of yacc.c */ -#line 107 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } +#line 121 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = SHELL_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } break; case 14: /* Line 1806 of yacc.c */ -#line 108 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 126 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 109 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 127 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 110 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = COND_PARAM; } +#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = EVAL_PARAM; } +#line 129 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(2) - (2)]); (yyval).type = SHELL_PARAM; } +#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 19: + +/* Line 1806 of yacc.c */ +#line 131 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 20: + +/* Line 1806 of yacc.c */ +#line 132 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } break; /* Line 1806 of yacc.c */ -#line 1554 "sapi/phpdbg/phpdbg_parser.c" +#line 1591 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1781,6 +1818,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 115 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 135 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index d0ba3b13604..ca9d8b08b3e 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -58,15 +58,17 @@ typedef void* yyscan_t; T_TRUTHY = 261, T_FALSY = 262, T_STRING = 263, - T_COLON = 264, - T_DCOLON = 265, - T_POUND = 266, - T_DIGITS = 267, - T_LITERAL = 268, - T_OPLINE = 269, - T_ID = 270, - T_INPUT = 271, - T_UNEXPECTED = 272 + T_SQUIGGLE = 264, + T_COLON = 265, + T_DCOLON = 266, + T_POUND = 267, + T_DIGITS = 268, + T_LITERAL = 269, + T_ADDR = 270, + T_OPCODE = 271, + T_ID = 272, + T_INPUT = 273, + T_UNEXPECTED = 274 }; #endif diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 24d24956f9d..98fbcdf5189 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -784,6 +784,9 @@ PHPDBG_COMMAND(break) /* {{{ */ case STR_PARAM: phpdbg_set_breakpoint_symbol(param->str, param->len TSRMLS_CC); break; + case OP_PARAM: + phpdbg_set_breakpoint_opcode(param->str, param->len TSRMLS_CC); + break; phpdbg_default_switch_case(); } From b82ad53b29eea3edb6174f176cb7f8b700eb0249 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 16:29:09 +0000 Subject: [PATCH 064/137] ... --- dev/phpdbg_lexer.l | 3 +- dev/phpdbg_parser.y | 7 +- phpdbg_cmd.c | 5 - phpdbg_cmd.h | 1 - phpdbg_lexer.c | 249 +++++++++++++++++++++----------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 193 ++++++++++++++++------------------ phpdbg_parser.h | 21 ++-- 8 files changed, 222 insertions(+), 259 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index ae8eeb78319..111df941049 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -35,7 +35,7 @@ T_IF ?i:"if" WS [ \r\n\t]+ DIGITS [0-9\.]+ -ID [^ \r\n\t:#~]+ +ID [^ \r\n\t:#]+ ADDR 0x[a-fA-F0-9]+ OPCODE ZEND_([A-Z])+ LITERAL \"(\\.|[^\\"])*\" @@ -46,7 +46,6 @@ INPUT [^\n]+ [#]{1} { return T_POUND; } [:]{2} { return T_DCOLON; } [:]{1} { return T_COLON; } - [~]{1} { return T_SQUIGGLE; } {T_EVAL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index a811ba870db..8155f670430 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -57,7 +57,6 @@ typedef void* yyscan_t; %token T_TRUTHY "truthy (true, on, yes or enabled)" %token T_FALSY "falsy (false, off, no or disabled)" %token T_STRING "string (some input, perhaps)" -%token T_SQUIGGLE "~ (squiggle)" %token T_COLON ": (colon)" %token T_DCOLON ":: (double colon)" %token T_POUND "# (pound sign)" @@ -82,11 +81,7 @@ parameters ; parameter - : T_SQUIGGLE T_DIGITS { - $$.type = OPLINE_PARAM; - $$.num = $2.num; - } - | T_ID T_COLON T_DIGITS { + : T_ID T_COLON T_DIGITS { $$.type = FILE_PARAM; $$.file.name = $1.str; $$.file.line = $3.num; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 3974edb8d10..cbd769ff4b4 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -446,10 +446,6 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) fprintf(stderr, "%s OP_PARAM(%s=%lu)\n", msg, param->str, param->len); break; - case OPLINE_PARAM: - fprintf(stderr, "%s OPLINE_PARAM(%ld)\n", msg, param->num); - break; - default: { /* not yet */ } @@ -580,7 +576,6 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param case 'f': verify_arg("file:line", top, FILE_PARAM); break; case 'c': verify_arg("condition", top, COND_PARAM); break; case 'o': verify_arg("opcode", top, OP_PARAM); break; - case 'O': verify_arg("opline", top, OPLINE_PARAM); break; case 'b': verify_arg("boolean", top, NUMERIC_PARAM); break; case '*': { /* do nothing */ } break; diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index d6cd19dfc10..2834ee06d37 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -44,7 +44,6 @@ typedef enum { SHELL_PARAM, COND_PARAM, OP_PARAM, - OPLINE_PARAM, ORIG_PARAM } phpdbg_param_type; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 590d0825d7a..9e6424ee08d 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 16 +#define YY_END_OF_BUFFER 17 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,16 +358,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[80] = +static yyconst flex_int16_t yy_accept[79] = { 0, - 0, 0, 0, 0, 18, 14, 16, 14, 1, 10, - 10, 3, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 4, 15, 15, 14, 16, 14, 0, 13, - 14, 10, 14, 2, 14, 14, 14, 14, 7, 9, - 14, 8, 14, 14, 14, 14, 15, 15, 13, 0, - 11, 14, 14, 14, 14, 9, 14, 14, 8, 14, - 14, 14, 5, 14, 14, 8, 14, 14, 14, 9, - 6, 14, 14, 14, 12, 14, 8, 9, 0 + 0, 0, 0, 0, 17, 13, 15, 13, 1, 9, + 9, 3, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 14, 14, 13, 15, 13, 0, 12, 13, + 9, 13, 2, 13, 13, 13, 13, 6, 8, 13, + 7, 13, 13, 13, 13, 14, 14, 12, 0, 10, + 13, 13, 13, 13, 8, 13, 13, 7, 13, 13, + 13, 4, 13, 13, 7, 13, 13, 13, 8, 5, + 13, 13, 13, 11, 13, 7, 8, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -385,7 +385,7 @@ static yyconst flex_int32_t yy_ec[256] = 35, 36, 1, 37, 38, 1, 1, 39, 1, 40, 41, 1, 1, 42, 43, 44, 45, 46, 1, 47, - 48, 1, 1, 1, 1, 49, 1, 1, 1, 1, + 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -402,113 +402,109 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[50] = +static yyconst flex_int32_t yy_meta[49] = { 0, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 2 + 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[85] = +static yyconst flex_int16_t yy_base[84] = { 0, - 0, 0, 48, 50, 139, 0, 52, 54, 246, 54, - 58, 129, 49, 48, 59, 55, 51, 60, 56, 55, - 64, 123, 246, 0, 79, 0, 82, 104, 72, 0, - 109, 109, 152, 246, 79, 79, 88, 85, 0, 0, - 105, 0, 107, 98, 102, 110, 0, 124, 246, 92, - 0, 118, 118, 112, 109, 0, 115, 121, 0, 73, - 125, 129, 0, 126, 136, 0, 49, 150, 156, 0, - 0, 182, 176, 199, 0, 200, 0, 0, 246, 234, - 70, 237, 240, 242 + 0, 0, 47, 49, 163, 0, 51, 53, 238, 53, + 57, 140, 48, 47, 58, 54, 50, 59, 55, 54, + 63, 107, 0, 78, 0, 81, 98, 81, 0, 103, + 107, 121, 238, 74, 78, 106, 99, 0, 0, 104, + 0, 106, 97, 100, 91, 0, 122, 238, 91, 0, + 116, 119, 120, 121, 0, 126, 132, 0, 65, 137, + 131, 0, 144, 141, 0, 45, 142, 148, 0, 0, + 174, 168, 191, 0, 192, 0, 0, 238, 226, 69, + 229, 232, 234 } ; -static yyconst flex_int16_t yy_def[85] = +static yyconst flex_int16_t yy_def[84] = { 0, - 79, 1, 80, 80, 79, 81, 79, 82, 79, 81, - 81, 79, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 79, 83, 83, 81, 79, 82, 84, 81, - 82, 81, 81, 79, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 83, 83, 79, 84, - 33, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 81, 81, 72, 81, 81, 81, 0, 79, - 79, 79, 79, 79 + 78, 1, 79, 79, 78, 80, 78, 81, 78, 80, + 80, 78, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 82, 82, 80, 78, 81, 83, 80, 81, + 80, 80, 78, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 82, 82, 78, 83, 32, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 71, 80, 80, 80, 0, 78, 78, + 78, 78, 78 } ; -static yyconst flex_int16_t yy_nxt[296] = +static yyconst flex_int16_t yy_nxt[287] = { 0, 6, 7, 7, 8, 9, 10, 11, 10, 12, 6, 6, 6, 13, 14, 15, 6, 6, 16, 6, 17, 18, 6, 19, 20, 6, 6, 21, 22, 6, 6, 6, 6, 6, 13, 14, 15, 6, 16, 6, 17, - 18, 6, 19, 20, 6, 6, 6, 21, 23, 25, - 7, 25, 7, 27, 27, 29, 29, 30, 29, 32, - 32, 32, 29, 32, 32, 32, 35, 36, 38, 39, - 26, 40, 43, 37, 41, 49, 44, 45, 72, 42, - 48, 27, 31, 27, 27, 67, 35, 36, 53, 38, - 39, 40, 43, 37, 79, 41, 44, 54, 45, 42, + 18, 6, 19, 20, 6, 6, 6, 21, 24, 7, + 24, 7, 26, 26, 28, 28, 29, 28, 31, 31, + 31, 28, 31, 31, 31, 34, 35, 37, 38, 25, + 39, 42, 36, 40, 71, 43, 44, 66, 41, 47, + 26, 30, 26, 26, 48, 34, 35, 52, 37, 38, + 39, 42, 36, 78, 40, 43, 51, 44, 41, 28, - 50, 52, 29, 55, 33, 29, 29, 30, 29, 53, - 29, 79, 29, 29, 32, 32, 32, 29, 54, 56, - 57, 52, 58, 55, 59, 48, 27, 61, 62, 60, - 63, 64, 31, 65, 66, 68, 46, 34, 79, 70, - 56, 57, 58, 79, 59, 79, 79, 69, 61, 62, - 63, 64, 29, 65, 71, 66, 68, 29, 51, 51, - 70, 51, 51, 51, 51, 51, 51, 69, 73, 74, - 79, 79, 79, 79, 71, 79, 79, 79, 79, 79, - 79, 79, 51, 51, 51, 51, 51, 51, 73, 76, - 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, - - 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 76, 77, 78, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 77, 78, 24, 24, 24, 28, 28, 28, - 47, 47, 29, 29, 29, 5, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79 + 28, 29, 28, 32, 28, 78, 28, 28, 52, 49, + 59, 28, 31, 31, 31, 53, 51, 54, 55, 56, + 45, 57, 58, 47, 26, 60, 30, 50, 50, 61, + 50, 50, 50, 50, 50, 50, 53, 54, 62, 55, + 56, 57, 58, 63, 64, 65, 60, 67, 33, 68, + 61, 50, 50, 50, 50, 50, 50, 69, 62, 70, + 72, 73, 78, 63, 64, 78, 65, 78, 67, 68, + 78, 78, 78, 78, 78, 78, 78, 78, 69, 70, + 72, 75, 73, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 75, 76, 77, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 76, 77, 23, 23, 23, 27, + 27, 27, 46, 46, 28, 28, 28, 5, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78 } ; -static yyconst flex_int16_t yy_chk[296] = +static yyconst flex_int16_t yy_chk[287] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, - 3, 4, 4, 7, 7, 8, 8, 8, 8, 10, - 10, 10, 8, 11, 11, 11, 13, 14, 15, 16, - 81, 17, 19, 14, 18, 29, 20, 21, 67, 18, - 25, 25, 8, 27, 27, 60, 13, 14, 36, 15, - 16, 17, 19, 14, 50, 18, 20, 37, 21, 18, + 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, + 4, 4, 7, 7, 8, 8, 8, 8, 10, 10, + 10, 8, 11, 11, 11, 13, 14, 15, 16, 80, + 17, 19, 14, 18, 66, 20, 21, 59, 18, 24, + 24, 8, 26, 26, 28, 13, 14, 35, 15, 16, + 17, 19, 14, 49, 18, 20, 34, 21, 18, 27, - 29, 35, 8, 38, 11, 28, 28, 28, 28, 36, - 31, 31, 28, 31, 32, 32, 32, 31, 37, 41, - 43, 35, 44, 38, 45, 48, 48, 52, 53, 46, - 54, 55, 28, 57, 58, 61, 22, 12, 5, 64, - 41, 43, 44, 0, 45, 0, 0, 62, 52, 53, - 54, 55, 28, 57, 65, 58, 61, 31, 33, 33, - 64, 33, 33, 33, 33, 33, 33, 62, 68, 69, - 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, - 0, 0, 33, 33, 33, 33, 33, 33, 68, 73, - 69, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 27, 27, 27, 11, 30, 30, 27, 30, 35, 28, + 45, 30, 31, 31, 31, 36, 34, 37, 40, 42, + 22, 43, 44, 47, 47, 51, 27, 32, 32, 52, + 32, 32, 32, 32, 32, 32, 36, 37, 53, 40, + 42, 43, 44, 54, 56, 57, 51, 60, 12, 61, + 52, 32, 32, 32, 32, 32, 32, 63, 53, 64, + 67, 68, 5, 54, 56, 0, 57, 0, 60, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, + 67, 72, 68, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 73, 74, 76, 0, 0, 0, 0, 0, 0, 0, + 71, 71, 72, 73, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 74, 76, 80, 80, 80, 82, 82, 82, - 83, 83, 84, 84, 84, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 79, 79 - + 0, 0, 0, 0, 73, 75, 79, 79, 79, 81, + 81, 81, 82, 82, 83, 83, 83, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78 } ; /* The intent behind this definition is that it'll catch @@ -534,7 +530,7 @@ static yyconst flex_int16_t yy_chk[296] = #include #define YY_NO_UNISTD_H 1 -#line 538 "sapi/phpdbg/phpdbg_lexer.c" +#line 534 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -774,7 +770,7 @@ YY_DECL #line 43 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 778 "sapi/phpdbg/phpdbg_lexer.c" +#line 774 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -829,13 +825,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 79 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 79 ); + while ( yy_current_state != 78 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -873,74 +869,69 @@ YY_RULE_SETUP case 4: YY_RULE_SETUP #line 49 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ return T_SQUIGGLE; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 50 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } YY_BREAK -case 6: +case 5: YY_RULE_SETUP -#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } YY_BREAK -case 7: +case 6: YY_RULE_SETUP -#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 59 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } YY_BREAK -case 8: +case 7: YY_RULE_SETUP -#line 65 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } YY_BREAK -case 9: +case 8: YY_RULE_SETUP -#line 70 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 69 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } YY_BREAK -case 10: +case 9: YY_RULE_SETUP -#line 75 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 74 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 11: +case 10: YY_RULE_SETUP -#line 80 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 79 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_ADDR; } YY_BREAK -case 12: +case 11: YY_RULE_SETUP -#line 85 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -948,10 +939,10 @@ YY_RULE_SETUP return T_OPCODE; } YY_BREAK -case 13: -/* rule 13 can match eol */ +case 12: +/* rule 12 can match eol */ YY_RULE_SETUP -#line 91 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -959,9 +950,9 @@ YY_RULE_SETUP return T_LITERAL; } YY_BREAK -case 14: +case 13: YY_RULE_SETUP -#line 97 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 96 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -970,9 +961,9 @@ YY_RULE_SETUP } YY_BREAK -case 15: +case 14: YY_RULE_SETUP -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 103 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -981,18 +972,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 16: -/* rule 16 can match eol */ +case 15: +/* rule 15 can match eol */ YY_RULE_SETUP -#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 110 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 17: +case 16: YY_RULE_SETUP -#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 996 "sapi/phpdbg/phpdbg_lexer.c" +#line 987 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1288,7 +1279,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 79 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1317,11 +1308,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 80 ) + if ( yy_current_state >= 79 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 79); + yy_is_jam = (yy_current_state == 78); return yy_is_jam ? 0 : yy_current_state; } @@ -2157,7 +2148,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 0395393613c..204ecb6c947 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index c252c7ab9d7..599758f44f8 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -153,17 +153,16 @@ typedef void* yyscan_t; T_TRUTHY = 261, T_FALSY = 262, T_STRING = 263, - T_SQUIGGLE = 264, - T_COLON = 265, - T_DCOLON = 266, - T_POUND = 267, - T_DIGITS = 268, - T_LITERAL = 269, - T_ADDR = 270, - T_OPCODE = 271, - T_ID = 272, - T_INPUT = 273, - T_UNEXPECTED = 274 + T_COLON = 264, + T_DCOLON = 265, + T_POUND = 266, + T_DIGITS = 267, + T_LITERAL = 268, + T_ADDR = 269, + T_OPCODE = 270, + T_ID = 271, + T_INPUT = 272, + T_UNEXPECTED = 273 }; #endif @@ -181,7 +180,7 @@ typedef int YYSTYPE; /* Line 343 of yacc.c */ -#line 185 "sapi/phpdbg/phpdbg_parser.c" +#line 184 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -398,22 +397,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 22 +#define YYFINAL 20 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 25 +#define YYLAST 23 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 20 +#define YYNTOKENS 19 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 20 +#define YYNRULES 19 /* YYNRULES -- Number of states. */ -#define YYNSTATES 29 +#define YYNSTATES 27 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 274 +#define YYMAXUTOK 273 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -448,7 +447,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19 + 15, 16, 17, 18 }; #if YYDEBUG @@ -456,28 +455,26 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 6, 8, 11, 14, 18, 22, - 28, 32, 35, 38, 41, 43, 45, 47, 49, 51, - 53 + 0, 0, 3, 5, 6, 8, 11, 15, 19, 25, + 29, 32, 35, 38, 40, 42, 44, 46, 48, 50 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 21, 0, -1, 22, -1, -1, 23, -1, 22, 23, - -1, 9, 13, -1, 17, 10, 13, -1, 17, 11, - 17, -1, 17, 11, 17, 12, 13, -1, 17, 12, - 13, -1, 5, 18, -1, 3, 18, -1, 4, 18, - -1, 16, -1, 15, -1, 14, -1, 6, -1, 7, - -1, 13, -1, 17, -1 + 20, 0, -1, 21, -1, -1, 22, -1, 21, 22, + -1, 16, 9, 12, -1, 16, 10, 16, -1, 16, + 10, 16, 11, 12, -1, 16, 11, 12, -1, 5, + 17, -1, 3, 17, -1, 4, 17, -1, 15, -1, + 14, -1, 13, -1, 6, -1, 7, -1, 12, -1, + 16, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 75, 75, 76, 80, 81, 85, 89, 94, 99, - 105, 111, 116, 121, 126, 127, 128, 129, 130, 131, - 132 + 0, 74, 74, 75, 79, 80, 84, 89, 94, 100, + 106, 111, 116, 121, 122, 123, 124, 125, 126, 127 }; #endif @@ -489,7 +486,7 @@ static const char *const yytname[] = "$end", "error", "$undefined", "\"eval\"", "\"shell\"", "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", - "\"string (some input, perhaps)\"", "\"~ (squiggle)\"", "\": (colon)\"", + "\"string (some input, perhaps)\"", "\": (colon)\"", "\":: (double colon)\"", "\"# (pound sign)\"", "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", "\"opcode\"", "\"identifier (command or function name)\"", @@ -504,24 +501,22 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274 + 265, 266, 267, 268, 269, 270, 271, 272, 273 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 20, 21, 21, 22, 22, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23 + 0, 19, 20, 20, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 1, 2, 2, 3, 3, 5, - 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, - 1 + 0, 2, 1, 0, 1, 2, 3, 3, 5, 3, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -529,31 +524,31 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 0, 17, 18, 0, 19, 16, 15, - 14, 20, 0, 2, 4, 12, 13, 11, 6, 0, - 0, 0, 1, 5, 7, 8, 10, 0, 9 + 3, 0, 0, 0, 16, 17, 18, 15, 14, 13, + 19, 0, 2, 4, 11, 12, 10, 0, 0, 0, + 1, 5, 6, 7, 9, 0, 8 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 12, 13, 14 + -1, 11, 12, 13 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -14 +#define YYPACT_NINF -10 static const yytype_int8 yypact[] = { - -3, -13, -11, -10, -14, -14, -4, -14, -14, -14, - -14, 5, 18, -3, -14, -14, -14, -14, -14, 6, - 3, 8, -14, -14, -14, 10, -14, 11, -14 + -3, -9, -2, -1, -10, -10, -10, -10, -10, -10, + -4, 14, -3, -10, -10, -10, -10, 5, 2, 7, + -10, -10, -10, 9, -10, 10, -10 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -14, -14, -14, 12 + -10, -10, -10, 11 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -562,31 +557,31 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 1, 2, 3, 4, 5, 15, 6, 16, 17, 18, - 7, 8, 9, 10, 11, 19, 20, 21, 22, 24, - 25, 26, 27, 0, 28, 23 + 1, 2, 3, 4, 5, 17, 18, 19, 14, 6, + 7, 8, 9, 10, 20, 15, 16, 22, 23, 24, + 25, 0, 26, 21 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-14)) + ((yystate) == (-10)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 5, 6, 7, 18, 9, 18, 18, 13, - 13, 14, 15, 16, 17, 10, 11, 12, 0, 13, - 17, 13, 12, -1, 13, 13 + 3, 4, 5, 6, 7, 9, 10, 11, 17, 12, + 13, 14, 15, 16, 0, 17, 17, 12, 16, 12, + 11, -1, 12, 12 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 3, 4, 5, 6, 7, 9, 13, 14, 15, - 16, 17, 21, 22, 23, 18, 18, 18, 13, 10, - 11, 12, 0, 23, 13, 17, 13, 12, 13 + 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, + 16, 20, 21, 22, 17, 17, 17, 9, 10, 11, + 0, 22, 12, 16, 12, 11, 12 }; #define yyerrok (yyerrstatus = 0) @@ -1435,24 +1430,25 @@ yyreduce: case 4: /* Line 1806 of yacc.c */ -#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 5: /* Line 1806 of yacc.c */ -#line 81 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 6: /* Line 1806 of yacc.c */ -#line 85 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = OPLINE_PARAM; - (yyval).num = (yyvsp[(2) - (2)]).num; +#line 84 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = FILE_PARAM; + (yyval).file.name = (yyvsp[(1) - (3)]).str; + (yyval).file.line = (yyvsp[(3) - (3)]).num; } break; @@ -1460,10 +1456,10 @@ yyreduce: /* Line 1806 of yacc.c */ #line 89 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = FILE_PARAM; - (yyval).file.name = (yyvsp[(1) - (3)]).str; - (yyval).file.line = (yyvsp[(3) - (3)]).num; + { + (yyval).type = METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (3)]).str; + (yyval).method.name = (yyvsp[(3) - (3)]).str; } break; @@ -1471,17 +1467,6 @@ yyreduce: /* Line 1806 of yacc.c */ #line 94 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = METHOD_PARAM; - (yyval).method.class = (yyvsp[(1) - (3)]).str; - (yyval).method.name = (yyvsp[(3) - (3)]).str; - } - break; - - case 9: - -/* Line 1806 of yacc.c */ -#line 99 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1490,10 +1475,10 @@ yyreduce: } break; - case 10: + case 9: /* Line 1806 of yacc.c */ -#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1502,12 +1487,23 @@ yyreduce: } break; + case 10: + +/* Line 1806 of yacc.c */ +#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = COND_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } + break; + case 11: /* Line 1806 of yacc.c */ #line 111 "sapi/phpdbg/dev/phpdbg_parser.y" { - (yyval).type = COND_PARAM; + (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; (yyval).len = (yyvsp[(2) - (2)]).len; } @@ -1517,8 +1513,8 @@ yyreduce: /* Line 1806 of yacc.c */ #line 116 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = EVAL_PARAM; + { + (yyval).type = SHELL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; (yyval).len = (yyvsp[(2) - (2)]).len; } @@ -1528,66 +1524,55 @@ yyreduce: /* Line 1806 of yacc.c */ #line 121 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = SHELL_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } + { (yyval) = (yyvsp[(1) - (1)]); } break; case 14: /* Line 1806 of yacc.c */ -#line 126 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 15: /* Line 1806 of yacc.c */ -#line 127 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 123 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 16: /* Line 1806 of yacc.c */ -#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 124 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1806 of yacc.c */ -#line 129 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 125 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1806 of yacc.c */ -#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 126 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1806 of yacc.c */ -#line 131 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 20: - -/* Line 1806 of yacc.c */ -#line 132 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 127 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; /* Line 1806 of yacc.c */ -#line 1591 "sapi/phpdbg/phpdbg_parser.c" +#line 1576 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1818,6 +1803,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 135 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index ca9d8b08b3e..413d3ae192e 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -58,17 +58,16 @@ typedef void* yyscan_t; T_TRUTHY = 261, T_FALSY = 262, T_STRING = 263, - T_SQUIGGLE = 264, - T_COLON = 265, - T_DCOLON = 266, - T_POUND = 267, - T_DIGITS = 268, - T_LITERAL = 269, - T_ADDR = 270, - T_OPCODE = 271, - T_ID = 272, - T_INPUT = 273, - T_UNEXPECTED = 274 + T_COLON = 264, + T_DCOLON = 265, + T_POUND = 266, + T_DIGITS = 267, + T_LITERAL = 268, + T_ADDR = 269, + T_OPCODE = 270, + T_ID = 271, + T_INPUT = 272, + T_UNEXPECTED = 273 }; #endif From a6eee49326d88c77616f557a1f368557f180fe55 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 17:47:02 +0000 Subject: [PATCH 065/137] case insensitive --- dev/phpdbg_lexer.l | 9 +- phpdbg_cmd.c | 6 +- phpdbg_lexer.c | 273 +++++++++++++++++++++------------------------ phpdbg_lexer.h | 2 +- 4 files changed, 131 insertions(+), 159 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 111df941049..5f4652fc3d3 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -37,8 +37,7 @@ WS [ \r\n\t]+ DIGITS [0-9\.]+ ID [^ \r\n\t:#]+ ADDR 0x[a-fA-F0-9]+ -OPCODE ZEND_([A-Z])+ -LITERAL \"(\\.|[^\\"])*\" +OPCODE ?i:ZEND_([A-Za-z])+ INPUT [^\n]+ %% @@ -87,12 +86,6 @@ INPUT [^\n]+ yylval->len = yyleng; return T_OPCODE; } - {LITERAL} { - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return T_LITERAL; - } {ID} { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index cbd769ff4b4..69aca21de88 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -621,9 +621,9 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * matches++; } } else { - - /* match full command name */ - if (memcmp(command->name, name->str, name->len) == SUCCESS) { + + /* match full, case insensitive, command name */ + if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { matched[matches] = command; matches++; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 9e6424ee08d..ba8980c27c6 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -349,8 +349,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 16 -#define YY_END_OF_BUFFER 17 +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -358,16 +358,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[79] = +static yyconst flex_int16_t yy_accept[72] = { 0, - 0, 0, 0, 0, 17, 13, 15, 13, 1, 9, - 9, 3, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 14, 14, 13, 15, 13, 0, 12, 13, - 9, 13, 2, 13, 13, 13, 13, 6, 8, 13, - 7, 13, 13, 13, 13, 14, 14, 12, 0, 10, - 13, 13, 13, 13, 8, 13, 13, 7, 13, 13, - 13, 4, 13, 13, 7, 13, 13, 13, 8, 5, - 13, 13, 13, 11, 13, 7, 8, 0 + 0, 0, 0, 0, 16, 12, 14, 1, 9, 9, + 3, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 13, 13, 12, 14, 9, 12, 2, 12, 12, + 12, 12, 6, 8, 12, 7, 12, 12, 12, 12, + 13, 13, 10, 12, 12, 12, 12, 8, 12, 12, + 7, 12, 12, 12, 4, 12, 12, 7, 12, 12, + 12, 8, 5, 12, 12, 12, 11, 12, 7, 8, + 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -375,17 +375,17 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 4, 5, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 6, 1, 7, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, - 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 16, 16, 19, 16, 20, 21, 16, - 16, 22, 23, 24, 25, 26, 16, 16, 27, 28, - 1, 29, 1, 1, 30, 1, 31, 32, 33, 34, + 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 5, 1, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 8, 1, 1, + 1, 1, 1, 1, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 15, 15, 18, 15, 19, 20, 15, + 15, 21, 22, 23, 24, 25, 15, 15, 26, 27, + 1, 1, 1, 1, 28, 1, 29, 30, 11, 31, - 35, 36, 1, 37, 38, 1, 1, 39, 1, 40, - 41, 1, 1, 42, 43, 44, 45, 46, 1, 47, - 48, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 32, 33, 15, 34, 35, 15, 15, 36, 15, 37, + 38, 15, 15, 39, 40, 41, 42, 43, 15, 44, + 45, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -402,109 +402,99 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[49] = +static yyconst flex_int32_t yy_meta[47] = { 0, - 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, + 1, 2, 3, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[84] = +static yyconst flex_int16_t yy_base[76] = { 0, - 0, 0, 47, 49, 163, 0, 51, 53, 238, 53, - 57, 140, 48, 47, 58, 54, 50, 59, 55, 54, - 63, 107, 0, 78, 0, 81, 98, 81, 0, 103, - 107, 121, 238, 74, 78, 106, 99, 0, 0, 104, - 0, 106, 97, 100, 91, 0, 122, 238, 91, 0, - 116, 119, 120, 121, 0, 126, 132, 0, 65, 137, - 131, 0, 144, 141, 0, 45, 142, 148, 0, 0, - 174, 168, 191, 0, 192, 0, 0, 238, 226, 69, - 229, 232, 234 + 0, 0, 45, 47, 146, 0, 49, 202, 48, 51, + 132, 42, 41, 52, 49, 42, 50, 51, 47, 57, + 58, 0, 70, 0, 72, 86, 90, 202, 54, 79, + 89, 88, 0, 0, 93, 0, 96, 87, 90, 94, + 0, 112, 0, 96, 106, 99, 105, 0, 114, 120, + 0, 122, 127, 120, 0, 126, 123, 0, 82, 124, + 130, 0, 0, 160, 131, 137, 168, 139, 0, 0, + 202, 196, 78, 199, 64 } ; -static yyconst flex_int16_t yy_def[84] = +static yyconst flex_int16_t yy_def[76] = { 0, - 78, 1, 79, 79, 78, 80, 78, 81, 78, 80, - 80, 78, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 82, 82, 80, 78, 81, 83, 80, 81, - 80, 80, 78, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 82, 82, 78, 83, 32, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 71, 80, 80, 80, 0, 78, 78, - 78, 78, 78 + 71, 1, 72, 72, 71, 73, 71, 71, 73, 73, + 71, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 74, 74, 73, 71, 73, 73, 71, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 74, 74, 27, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, + 73, 73, 73, 75, 73, 73, 75, 73, 73, 73, + 0, 71, 71, 71, 71 } ; -static yyconst flex_int16_t yy_nxt[287] = +static yyconst flex_int16_t yy_nxt[249] = { 0, - 6, 7, 7, 8, 9, 10, 11, 10, 12, 6, - 6, 6, 13, 14, 15, 6, 6, 16, 6, 17, - 18, 6, 19, 20, 6, 6, 21, 22, 6, 6, - 6, 6, 6, 13, 14, 15, 6, 16, 6, 17, - 18, 6, 19, 20, 6, 6, 6, 21, 24, 7, - 24, 7, 26, 26, 28, 28, 29, 28, 31, 31, - 31, 28, 31, 31, 31, 34, 35, 37, 38, 25, - 39, 42, 36, 40, 71, 43, 44, 66, 41, 47, - 26, 30, 26, 26, 48, 34, 35, 52, 37, 38, - 39, 42, 36, 78, 40, 43, 51, 44, 41, 28, + 6, 7, 7, 8, 9, 10, 9, 11, 6, 6, + 6, 12, 13, 14, 6, 6, 15, 6, 16, 17, + 6, 18, 19, 6, 6, 20, 21, 6, 6, 6, + 12, 13, 14, 6, 15, 6, 16, 17, 6, 18, + 19, 6, 6, 6, 20, 21, 23, 7, 23, 7, + 25, 25, 26, 26, 26, 26, 26, 26, 29, 30, + 32, 34, 33, 35, 67, 31, 37, 38, 36, 39, + 40, 42, 25, 25, 25, 44, 29, 30, 24, 34, + 32, 33, 35, 31, 37, 38, 36, 45, 39, 40, + 26, 26, 26, 44, 27, 43, 43, 46, 43, 43, - 28, 29, 28, 32, 28, 78, 28, 28, 52, 49, - 59, 28, 31, 31, 31, 53, 51, 54, 55, 56, - 45, 57, 58, 47, 26, 60, 30, 50, 50, 61, - 50, 50, 50, 50, 50, 50, 53, 54, 62, 55, - 56, 57, 58, 63, 64, 65, 60, 67, 33, 68, - 61, 50, 50, 50, 50, 50, 50, 69, 62, 70, - 72, 73, 78, 63, 64, 78, 65, 78, 67, 68, - 78, 78, 78, 78, 78, 78, 78, 78, 69, 70, - 72, 75, 73, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 43, 43, 43, 43, 53, 47, 48, 45, 49, 64, + 50, 51, 52, 42, 25, 54, 55, 46, 43, 43, + 43, 43, 43, 47, 53, 48, 56, 49, 50, 51, + 52, 57, 58, 59, 55, 54, 60, 61, 62, 28, + 63, 65, 66, 68, 56, 71, 71, 71, 69, 57, + 70, 58, 59, 71, 71, 61, 60, 62, 63, 65, + 24, 66, 68, 71, 24, 24, 24, 69, 24, 70, + 71, 71, 24, 24, 24, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 24, 71, 71, + 71, 71, 71, 71, 71, 24, 22, 22, 22, 41, - 74, 74, 75, 76, 77, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 76, 77, 23, 23, 23, 27, - 27, 27, 46, 46, 28, 28, 28, 5, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78 - } ; - -static yyconst flex_int16_t yy_chk[287] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, - 4, 4, 7, 7, 8, 8, 8, 8, 10, 10, - 10, 8, 11, 11, 11, 13, 14, 15, 16, 80, - 17, 19, 14, 18, 66, 20, 21, 59, 18, 24, - 24, 8, 26, 26, 28, 13, 14, 35, 15, 16, - 17, 19, 14, 49, 18, 20, 34, 21, 18, 27, - - 27, 27, 27, 11, 30, 30, 27, 30, 35, 28, - 45, 30, 31, 31, 31, 36, 34, 37, 40, 42, - 22, 43, 44, 47, 47, 51, 27, 32, 32, 52, - 32, 32, 32, 32, 32, 32, 36, 37, 53, 40, - 42, 43, 44, 54, 56, 57, 51, 60, 12, 61, - 52, 32, 32, 32, 32, 32, 32, 63, 53, 64, - 67, 68, 5, 54, 56, 0, 57, 0, 60, 61, - 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, - 67, 72, 68, 71, 71, 71, 71, 71, 71, 71, + 41, 5, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71 + } ; - 71, 71, 72, 73, 75, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 73, 75, 79, 79, 79, 81, - 81, 81, 82, 82, 83, 83, 83, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78 +static yyconst flex_int16_t yy_chk[249] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, + 7, 7, 9, 9, 9, 10, 10, 10, 12, 13, + 14, 16, 15, 17, 75, 13, 18, 19, 17, 20, + 21, 23, 23, 25, 25, 29, 12, 13, 73, 16, + 14, 15, 17, 13, 18, 19, 17, 30, 20, 21, + 26, 26, 26, 29, 10, 27, 27, 31, 27, 27, + + 27, 27, 27, 27, 44, 32, 35, 30, 37, 59, + 38, 39, 40, 42, 42, 45, 46, 31, 27, 27, + 27, 27, 27, 32, 44, 35, 47, 37, 38, 39, + 40, 49, 50, 52, 46, 45, 53, 54, 56, 11, + 57, 60, 61, 65, 47, 5, 0, 0, 66, 49, + 68, 50, 52, 0, 0, 54, 53, 56, 57, 60, + 64, 61, 65, 0, 64, 64, 64, 66, 67, 68, + 0, 0, 67, 67, 67, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, + 0, 0, 0, 0, 0, 67, 72, 72, 72, 74, + + 74, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71 } ; /* The intent behind this definition is that it'll catch @@ -530,7 +520,7 @@ static yyconst flex_int16_t yy_chk[287] = #include #define YY_NO_UNISTD_H 1 -#line 534 "sapi/phpdbg/phpdbg_lexer.c" +#line 524 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -768,9 +758,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 43 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 774 "sapi/phpdbg/phpdbg_lexer.c" +#line 764 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -825,13 +815,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 79 ) + if ( yy_current_state >= 72 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 78 ); + while ( yy_current_state != 71 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -853,22 +843,22 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_POUND; } YY_BREAK case 2: YY_RULE_SETUP -#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_DCOLON; } YY_BREAK case 3: YY_RULE_SETUP -#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_COLON; } YY_BREAK case 4: YY_RULE_SETUP -#line 49 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -877,7 +867,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 53 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -886,7 +876,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 59 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 58 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -895,7 +885,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 64 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -904,7 +894,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 69 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; @@ -913,7 +903,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 74 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -922,7 +912,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 79 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); @@ -931,7 +921,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 84 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 83 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -940,19 +930,8 @@ YY_RULE_SETUP } YY_BREAK case 12: -/* rule 12 can match eol */ YY_RULE_SETUP -#line 90 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return T_LITERAL; - } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 96 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 89 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -961,9 +940,9 @@ YY_RULE_SETUP } YY_BREAK -case 14: +case 13: YY_RULE_SETUP -#line 103 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 96 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -972,18 +951,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 15: -/* rule 15 can match eol */ +case 14: +/* rule 14 can match eol */ YY_RULE_SETUP -#line 110 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 103 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 16: +case 15: YY_RULE_SETUP -#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 987 "sapi/phpdbg/phpdbg_lexer.c" +#line 966 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1279,7 +1258,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 79 ) + if ( yy_current_state >= 72 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1308,11 +1287,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 79 ) + if ( yy_current_state >= 72 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 78); + yy_is_jam = (yy_current_state == 71); return yy_is_jam ? 0 : yy_current_state; } @@ -2148,7 +2127,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 204ecb6c947..b86554c3804 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -338,7 +338,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 111 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 345 "sapi/phpdbg/phpdbg_lexer.h" From c3a897bf3d8f7e83536e102638c0e12d9dd57a7e Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 18:01:50 +0000 Subject: [PATCH 066/137] introduce proper support for file:#opline --- dev/phpdbg_parser.y | 5 ++ phpdbg_break.c | 8 -- phpdbg_break.h | 1 - phpdbg_cmd.c | 23 ++++-- phpdbg_cmd.h | 1 + phpdbg_help.c | 6 +- phpdbg_parser.c | 173 ++++++++++++++++++++++++-------------------- phpdbg_prompt.c | 3 + 8 files changed, 124 insertions(+), 96 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 8155f670430..57184ca9197 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -86,6 +86,11 @@ parameter $$.file.name = $1.str; $$.file.line = $3.num; } + | T_ID T_COLON T_POUND T_DIGITS { + $$.type = NUMERIC_FILE_PARAM; + $$.file.name = $1.str; + $$.file.line = $4.num; + } | T_ID T_DCOLON T_ID { $$.type = METHOD_PARAM; $$.method.class = $1.str; diff --git a/phpdbg_break.c b/phpdbg_break.c index b83bdffe343..79091d27e67 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -35,19 +35,11 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_BREAK_COMMAND_D(address, "specify breakpoint by address", 'a', break_address, NULL, "f"), PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), PHPDBG_END_COMMAND }; -PHPDBG_BREAK(address) /* {{{ */ -{ - phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); - - return SUCCESS; -} /* }}} */ - PHPDBG_BREAK(at) /* {{{ */ { phpdbg_set_breakpoint_at(param TSRMLS_CC); diff --git a/phpdbg_break.h b/phpdbg_break.h index 50d855026c9..dc06da62b79 100644 --- a/phpdbg_break.h +++ b/phpdbg_break.h @@ -29,7 +29,6 @@ /** * Printer Forward Declarations */ -PHPDBG_BREAK(address); PHPDBG_BREAK(at); PHPDBG_BREAK(del); diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 69aca21de88..88eee421141 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -418,6 +418,10 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg) fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr); break; + case NUMERIC_FILE_PARAM: + fprintf(stderr, "%s NUMERIC_FILE_PARAM(%s:#%lu)\n", msg, param->file.name, param->file.line); + break; + case FILE_PARAM: fprintf(stderr, "%s FILE_PARAM(%s:%lu)\n", msg, param->file.name, param->file.line); break; @@ -465,16 +469,25 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { next = remove->next; switch (remove->type) { - case STR_PARAM: - if (remove->str) { + case NUMERIC_METHOD_PARAM: + case METHOD_PARAM: + if (remove->method.class) + free(remove->method.class); + if (remove->method.name) + free(remove->method.name); + break; + + case NUMERIC_FUNCTION_PARAM: + case STR_PARAM: + case OP_PARAM: + if (remove->str) free(remove->str); - } break; + case NUMERIC_FILE_PARAM: case FILE_PARAM: - if (remove->file.name) { + if (remove->file.name) free(remove->file.name); - } break; default: { diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 2834ee06d37..dd82faca50e 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -34,6 +34,7 @@ typedef enum { EMPTY_PARAM = 0, ADDR_PARAM, FILE_PARAM, + NUMERIC_FILE_PARAM, METHOD_PARAM, STR_PARAM, NUMERIC_PARAM, diff --git a/phpdbg_help.c b/phpdbg_help.c index ae37f9b720b..993a9c99099 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -540,9 +540,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P b \\\\my\\\\class::method#2" CR " Break at the opline #2 of the method \\\\my\\\\class::method" CR CR -" $P break address test.php:3" CR -" $P b a test.php:3" CR -" Break at the 3rd opline in test.php" CR CR +" $P break test.php:#3" CR +" $P b test.php:#3" CR +" Break at opline #3 in test.php" CR CR " $P break if $cnt > 10" CR " $P b if $cnt > 10" CR diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 599758f44f8..ab7c7189547 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -399,16 +399,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 20 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 23 +#define YYLAST 25 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 19 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 19 +#define YYNRULES 20 /* YYNRULES -- Number of states. */ -#define YYNSTATES 27 +#define YYNSTATES 29 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -455,26 +455,28 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 6, 8, 11, 15, 19, 25, - 29, 32, 35, 38, 40, 42, 44, 46, 48, 50 + 0, 0, 3, 5, 6, 8, 11, 15, 20, 24, + 30, 34, 37, 40, 43, 45, 47, 49, 51, 53, + 55 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { 20, 0, -1, 21, -1, -1, 22, -1, 21, 22, - -1, 16, 9, 12, -1, 16, 10, 16, -1, 16, - 10, 16, 11, 12, -1, 16, 11, 12, -1, 5, - 17, -1, 3, 17, -1, 4, 17, -1, 15, -1, - 14, -1, 13, -1, 6, -1, 7, -1, 12, -1, - 16, -1 + -1, 16, 9, 12, -1, 16, 9, 11, 12, -1, + 16, 10, 16, -1, 16, 10, 16, 11, 12, -1, + 16, 11, 12, -1, 5, 17, -1, 3, 17, -1, + 4, 17, -1, 15, -1, 14, -1, 13, -1, 6, + -1, 7, -1, 12, -1, 16, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 74, 74, 75, 79, 80, 84, 89, 94, 100, - 106, 111, 116, 121, 122, 123, 124, 125, 126, 127 + 0, 74, 74, 75, 79, 80, 84, 89, 94, 99, + 105, 111, 116, 121, 126, 127, 128, 129, 130, 131, + 132 }; #endif @@ -509,14 +511,16 @@ static const yytype_uint16 yytoknum[] = static const yytype_uint8 yyr1[] = { 0, 19, 20, 20, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22 + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 1, 2, 3, 3, 5, 3, - 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 + 0, 2, 1, 0, 1, 2, 3, 4, 3, 5, + 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, + 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -524,9 +528,9 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 0, 16, 17, 18, 15, 14, 13, - 19, 0, 2, 4, 11, 12, 10, 0, 0, 0, - 1, 5, 6, 7, 9, 0, 8 + 3, 0, 0, 0, 17, 18, 19, 16, 15, 14, + 20, 0, 2, 4, 12, 13, 11, 0, 0, 0, + 1, 5, 0, 6, 8, 10, 7, 0, 9 }; /* YYDEFGOTO[NTERM-NUM]. */ @@ -540,15 +544,15 @@ static const yytype_int8 yydefgoto[] = #define YYPACT_NINF -10 static const yytype_int8 yypact[] = { - -3, -9, -2, -1, -10, -10, -10, -10, -10, -10, - -4, 14, -3, -10, -10, -10, -10, 5, 2, 7, - -10, -10, -10, 9, -10, 10, -10 + -3, -9, -1, 0, -10, -10, -10, -10, -10, -10, + -4, 18, -3, -10, -10, -10, -10, 3, 4, 7, + -10, -10, 9, -10, 11, -10, -10, 12, -10 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -10, -10, -10, 11 + -10, -10, -10, 13 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -558,8 +562,8 @@ static const yytype_int8 yypgoto[] = static const yytype_uint8 yytable[] = { 1, 2, 3, 4, 5, 17, 18, 19, 14, 6, - 7, 8, 9, 10, 20, 15, 16, 22, 23, 24, - 25, 0, 26, 21 + 7, 8, 9, 10, 22, 23, 15, 16, 20, 25, + 24, 26, 27, 0, 28, 21 }; #define yypact_value_is_default(yystate) \ @@ -571,8 +575,8 @@ static const yytype_uint8 yytable[] = static const yytype_int8 yycheck[] = { 3, 4, 5, 6, 7, 9, 10, 11, 17, 12, - 13, 14, 15, 16, 0, 17, 17, 12, 16, 12, - 11, -1, 12, 12 + 13, 14, 15, 16, 11, 12, 17, 17, 0, 12, + 16, 12, 11, -1, 12, 12 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -581,7 +585,7 @@ static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 20, 21, 22, 17, 17, 17, 9, 10, 11, - 0, 22, 12, 16, 12, 11, 12 + 0, 22, 11, 12, 16, 12, 12, 11, 12 }; #define yyerrok (yyerrstatus = 0) @@ -1456,10 +1460,10 @@ yyreduce: /* Line 1806 of yacc.c */ #line 89 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = METHOD_PARAM; - (yyval).method.class = (yyvsp[(1) - (3)]).str; - (yyval).method.name = (yyvsp[(3) - (3)]).str; + { + (yyval).type = NUMERIC_FILE_PARAM; + (yyval).file.name = (yyvsp[(1) - (4)]).str; + (yyval).file.line = (yyvsp[(4) - (4)]).num; } break; @@ -1467,6 +1471,17 @@ yyreduce: /* Line 1806 of yacc.c */ #line 94 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = METHOD_PARAM; + (yyval).method.class = (yyvsp[(1) - (3)]).str; + (yyval).method.name = (yyvsp[(3) - (3)]).str; + } + break; + + case 9: + +/* Line 1806 of yacc.c */ +#line 99 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1475,10 +1490,10 @@ yyreduce: } break; - case 9: + case 10: /* Line 1806 of yacc.c */ -#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1487,23 +1502,12 @@ yyreduce: } break; - case 10: - -/* Line 1806 of yacc.c */ -#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = COND_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } - break; - case 11: /* Line 1806 of yacc.c */ #line 111 "sapi/phpdbg/dev/phpdbg_parser.y" { - (yyval).type = EVAL_PARAM; + (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; (yyval).len = (yyvsp[(2) - (2)]).len; } @@ -1513,8 +1517,8 @@ yyreduce: /* Line 1806 of yacc.c */ #line 116 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = SHELL_PARAM; + { + (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; (yyval).len = (yyvsp[(2) - (2)]).len; } @@ -1524,55 +1528,66 @@ yyreduce: /* Line 1806 of yacc.c */ #line 121 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } + { + (yyval).type = SHELL_PARAM; + (yyval).str = (yyvsp[(2) - (2)]).str; + (yyval).len = (yyvsp[(2) - (2)]).len; + } break; case 14: -/* Line 1806 of yacc.c */ -#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 15: - -/* Line 1806 of yacc.c */ -#line 123 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 16: - -/* Line 1806 of yacc.c */ -#line 124 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 17: - -/* Line 1806 of yacc.c */ -#line 125 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 18: - /* Line 1806 of yacc.c */ #line 126 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 19: + case 15: /* Line 1806 of yacc.c */ #line 127 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; + case 16: + +/* Line 1806 of yacc.c */ +#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 17: + +/* Line 1806 of yacc.c */ +#line 129 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 18: + +/* Line 1806 of yacc.c */ +#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 19: + +/* Line 1806 of yacc.c */ +#line 131 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 20: + +/* Line 1806 of yacc.c */ +#line 132 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + /* Line 1806 of yacc.c */ -#line 1576 "sapi/phpdbg/phpdbg_parser.c" +#line 1591 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1803,6 +1818,6 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 135 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 98fbcdf5189..3b147b3a6f6 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -778,6 +778,9 @@ PHPDBG_COMMAND(break) /* {{{ */ case FILE_PARAM: phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break; + case NUMERIC_FILE_PARAM: + phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); + break; case COND_PARAM: phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC); break; From f13fdbe9a01041219ff3f4bab60ae1059d952dba Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 18:05:11 +0000 Subject: [PATCH 067/137] update export function --- phpdbg_bp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 53415a31488..1d446fae73e 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -135,27 +135,27 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ switch (brake->type) { case PHPDBG_BREAK_FILE: { fprintf(handle, - "break file %s:%lu\n", + "break %s:%lu\n", ((phpdbg_breakfile_t*)brake)->filename, ((phpdbg_breakfile_t*)brake)->line); } break; case PHPDBG_BREAK_SYM: { fprintf(handle, - "break func %s\n", + "break %s\n", ((phpdbg_breaksymbol_t*)brake)->symbol); } break; case PHPDBG_BREAK_METHOD: { fprintf(handle, - "break method %s::%s\n", + "break %s::%s\n", ((phpdbg_breakmethod_t*)brake)->class_name, ((phpdbg_breakmethod_t*)brake)->func_name); } break; case PHPDBG_BREAK_METHOD_OPLINE: { fprintf(handle, - "break address %s::%s#%ld\n", + "break %s::%s#%ld\n", ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); @@ -163,21 +163,21 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_FUNCTION_OPLINE: { fprintf(handle, - "break address %s#%ld\n", + "break %s#%ld\n", ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_FILE_OPLINE: { fprintf(handle, - "break address %s:%ld\n", + "break %s:#%ld\n", ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_OPCODE: { fprintf(handle, - "break op %s\n", + "break %s\n", ((phpdbg_breakop_t*)brake)->name); } break; @@ -209,7 +209,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ } } else { fprintf( - handle, "break on %s\n", conditional->code); + handle, "break if %s\n", conditional->code); } } break; } From d1b02fe2fed850a79a0fce95addbf8188f241e9d Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 18:12:52 +0000 Subject: [PATCH 068/137] ... --- phpdbg_cmd.h | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index dd82faca50e..8028d7ddbc3 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -113,20 +113,13 @@ typedef struct { } phpdbg_frame_t; /* }}} */ - - /* * Workflow: -* 1) read input -* input takes the line from console, creates argc/argv -* 2) parse parameters into suitable types based on arg_type -* takes input from 1) and arg_type and creates parameters -* 3) do command -* executes commands -* 4) destroy parameters -* cleans up what was allocated by creation of parameters -* 5) destroy input -* cleans up what was allocated by creation of input +* 1) the lexer/parser creates a stack of commands and arguments from input +* 2) the commands at the top of the stack are resolved sensibly using aliases, abbreviations and case insensitive matching +* 3) the remaining arguments in the stack are verified (optionally) against the handlers declared argument specification +* 4) the handler is called passing the top of the stack as the only parameter +* 5) the stack is destroyed upon return from the handler */ /* From 28debb47173b5ca7f48a0199d6b6a330b80857ff Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 18:52:06 +0000 Subject: [PATCH 069/137] ... --- dev/phpdbg_parser.y | 2 +- phpdbg.h | 2 +- phpdbg_cmd.c | 22 ++++++++++++++-------- phpdbg_prompt.c | 2 -- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 57184ca9197..a524352e2a3 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -94,7 +94,7 @@ parameter | T_ID T_DCOLON T_ID { $$.type = METHOD_PARAM; $$.method.class = $1.str; - $$.method.name = $3.str; + $$.method.name = $3.str; } | T_ID T_DCOLON T_ID T_POUND T_DIGITS { $$.type = NUMERIC_METHOD_PARAM; diff --git a/phpdbg.h b/phpdbg.h index 414500cab72..670a831e173 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -181,7 +181,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ phpdbg_command_t *lcmd; /* last command */ - phpdbg_param_t lparam; /* last param */ + phpdbg_param_t lparam; /* last param */ zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 88eee421141..416aab8a423 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -236,6 +236,11 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des dest->str = estrndup(src->str, src->len); dest->len = src->len; break; + + case OP_PARAM: + dest->str = estrndup(src->str, src->len); + dest->len = src->len; + break; case ADDR_PARAM: dest->addr = src->addr; @@ -250,6 +255,7 @@ PHPDBG_API void phpdbg_copy_param(const phpdbg_param_t* src, phpdbg_param_t* des dest->method.name = estrdup(src->method.name); break; + case NUMERIC_FILE_PARAM: case FILE_PARAM: dest->file.name = estrdup(src->file.name); dest->file.line = src->file.line; @@ -712,7 +718,7 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * /* {{{ */ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { - phpdbg_param_t *command = NULL; + phpdbg_param_t *top = NULL; const phpdbg_command_t *handler = NULL; if (stack->type != STACK_PARAM) { @@ -727,22 +733,22 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { return FAILURE; } - command = (phpdbg_param_t*) stack->next; + top = (phpdbg_param_t*) stack->next; - switch (command->type) { + switch (top->type) { case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(eval)(command TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(eval)(top TSRMLS_CC); case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(shell)(command TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(shell)(top TSRMLS_CC); case STR_PARAM: { handler = phpdbg_stack_resolve( - phpdbg_prompt_commands, NULL, &command, why); + phpdbg_prompt_commands, NULL, &top, why); if (handler) { - if (phpdbg_stack_verify(handler, &command, why) == SUCCESS) { - return handler->handler(command TSRMLS_CC); + if (phpdbg_stack_verify(handler, &top, why) == SUCCESS) { + return handler->handler(top TSRMLS_CC); } } } return FAILURE; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 3b147b3a6f6..6d7cbb0b971 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -38,8 +38,6 @@ #include "phpdbg_lexer.h" #include "phpdbg_parser.h" -int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); -void phpdbg_stack_free(phpdbg_param_t *stack); int yyparse(phpdbg_param_t *stack, yyscan_t scanner); /* {{{ command declarations */ From 1c5f8ca7e10997ba3742e2ff9de26408297c4c82 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 19:05:20 +0000 Subject: [PATCH 070/137] verify noargs --- phpdbg_cmd.c | 14 +++++++++++--- phpdbg_prompt.c | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 416aab8a423..4d34be74a91 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -532,7 +532,7 @@ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) } /* }}} */ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC) { - if (command && command->args) { + if (command) { char buffer[128] = {0,}; const phpdbg_param_t *top = (stack != NULL) ? *stack : NULL; const char *arg = command->args; @@ -542,8 +542,16 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param zend_bool optional = 0; /* check for arg spec */ - if (!(arg) || !(*arg)) - return SUCCESS; + if (!(arg) || !(*arg)) { + if (!top) { + return SUCCESS; + } + + asprintf(why, + "%s expected no arguments", + phpdbg_command_name(command, buffer)); + return FAILURE; + } least = 0L; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 6d7cbb0b971..25f2a3abd36 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -52,7 +52,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, "s"), - PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 0), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "*|c"), PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"), PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"), PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), @@ -63,7 +63,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, "s"), - PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 0), + PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), PHPDBG_END_COMMAND }; /* }}} */ From bab960069c70693320aa32529f29230bb0c52277 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 19:37:16 +0000 Subject: [PATCH 071/137] ... --- phpdbg_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 4d34be74a91..95e16423688 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -585,7 +585,7 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param return FAILURE; \ } - while (arg) { + while (arg && *arg) { current++; switch (*arg) { From 1b92ce9a1b63df51bc93ac247a0a6f408a4b3e38 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 20:42:15 +0000 Subject: [PATCH 072/137] call register --- phpdbg_cmd.c | 5 +- phpdbg_parser.c | 2 +- phpdbg_prompt.c | 305 +++++++++++++++++++++++------------------------- 3 files changed, 148 insertions(+), 164 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 95e16423688..813911d9a3f 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -502,12 +502,15 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { } free(remove); + remove = NULL; - if (next) + if (next) remove = next; else break; } } + + stack->next = NULL; } /* }}} */ /* {{{ */ diff --git a/phpdbg_parser.c b/phpdbg_parser.c index ab7c7189547..4a0695d1a26 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -1474,7 +1474,7 @@ yyreduce: { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; - (yyval).method.name = (yyvsp[(3) - (3)]).str; + (yyval).method.name = (yyvsp[(3) - (3)]).str; } break; diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 25f2a3abd36..880e58b323b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -51,8 +51,8 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), - PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, "s"), - PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "*|c"), + PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 0), + PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, "|*c"), PHPDBG_COMMAND_D(back, "show trace", 't', NULL, "|n"), PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, "|n"), PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, "*"), @@ -72,9 +72,11 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ */ { - phpdbg_param_t *name = stack; + phpdbg_param_t *name = NULL; - if (name->type == STR_PARAM) { + if (stack->type == STACK_PARAM) { + name = stack->next; + if (zend_hash_exists( &PHPDBG_G(registered), name->str, name->len+1)) { @@ -93,9 +95,9 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * fci.retval_ptr_ptr = &fretval; fci.no_separation = 1; - if (stack->next) { + if (name->next) { zval params; - phpdbg_param_t *next = stack->next; + phpdbg_param_t *next = name->next; array_init(¶ms); @@ -206,20 +208,48 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ goto next_line; } - /*{ - phpdbg_param_t *input = phpdbg_read_input(cmd TSRMLS_CC); - switch (phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { - case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { - phpdbg_error("Unrecognized command in %s:%d: %s!", init_file, line, input->string); - } - } + { + char *why = NULL; + char *input = phpdbg_read_input(cmd TSRMLS_CC); + phpdbg_param_t stack; + yyscan_t scanner; + YY_BUFFER_STATE state; + + phpdbg_init_param(&stack, STACK_PARAM); + + if (yylex_init(&scanner)) { + phpdbg_error( + "could not initialize scanner"); break; } - phpdbg_destroy_input(&input TSRMLS_CC); - }*/ + state = yy_scan_string(input, scanner); + + if (yyparse(&stack, scanner) <= 0) { + switch (phpdbg_stack_execute(&stack, &why)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_error( + "Unrecognized command in %s:%d: %s, %s!", + init_file, line, input, why); + } + } + break; + } + } + + if (why) { + free(why); + why = NULL; + } + + yy_delete_buffer(state, scanner); + yylex_destroy(scanner); + + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); + } } next_line: line++; @@ -281,47 +311,40 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS PHPDBG_COMMAND(exec) /* {{{ */ { - switch (param->type) { - case STR_PARAM: { - struct stat sb; + struct stat sb; - if (VCWD_STAT(param->str, &sb) != FAILURE) { - if (sb.st_mode & (S_IFREG|S_IFLNK)) { - char *res = phpdbg_resolve_path(param->str TSRMLS_CC); - size_t res_len = strlen(res); + if (VCWD_STAT(param->str, &sb) != FAILURE) { + if (sb.st_mode & (S_IFREG|S_IFLNK)) { + char *res = phpdbg_resolve_path(param->str TSRMLS_CC); + size_t res_len = strlen(res); - if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { + if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { - if (PHPDBG_G(exec)) { - phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); - efree(PHPDBG_G(exec)); - PHPDBG_G(exec) = NULL; - PHPDBG_G(exec_len) = 0L; - } - - if (PHPDBG_G(ops)) { - phpdbg_notice("Destroying compiled opcodes"); - phpdbg_clean(0 TSRMLS_CC); - } - - PHPDBG_G(exec) = res; - PHPDBG_G(exec_len) = res_len; - - phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); - } else { - phpdbg_notice("Execution context not changed"); - } - } else { - phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str); + if (PHPDBG_G(exec)) { + phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); + efree(PHPDBG_G(exec)); + PHPDBG_G(exec) = NULL; + PHPDBG_G(exec_len) = 0L; } + + if (PHPDBG_G(ops)) { + phpdbg_notice("Destroying compiled opcodes"); + phpdbg_clean(0 TSRMLS_CC); + } + + PHPDBG_G(exec) = res; + PHPDBG_G(exec_len) = res_len; + + phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); } else { - phpdbg_error("Cannot stat %s, ensure the file exists", param->str); + phpdbg_notice("Execution context not changed"); } - } break; - - phpdbg_default_switch_case(); + } else { + phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str); + } + } else { + phpdbg_error("Cannot stat %s, ensure the file exists", param->str); } - return SUCCESS; } /* }}} */ @@ -372,21 +395,15 @@ PHPDBG_COMMAND(compile) /* {{{ */ PHPDBG_COMMAND(step) /* {{{ */ { - switch (param->type) { - case NUMERIC_PARAM: { - if (param->num) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - } else { - PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; - } - - phpdbg_notice("Stepping %s", - (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - } break; - - phpdbg_default_switch_case(); + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; } + phpdbg_notice("Stepping %s", + (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + return SUCCESS; } /* }}} */ @@ -491,15 +508,9 @@ PHPDBG_COMMAND(leave) /* {{{ */ PHPDBG_COMMAND(frame) /* {{{ */ { - if (!param || param->type == EMPTY_PARAM) { + if (!param) { phpdbg_notice("Currently in frame #%d", PHPDBG_G(frame).num); - } else switch (param->type) { - case NUMERIC_PARAM: - phpdbg_switch_frame(param->num TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } + } else phpdbg_switch_frame(param->num TSRMLS_CC); return SUCCESS; } /* }}} */ @@ -675,14 +686,10 @@ PHPDBG_COMMAND(back) /* {{{ */ return SUCCESS; } - if (!param || param->type == EMPTY_PARAM) { + if (!param) { phpdbg_dump_backtrace(0 TSRMLS_CC); - } else switch (param->type) { - case NUMERIC_PARAM: - phpdbg_dump_backtrace(param->num TSRMLS_CC); - break; - - phpdbg_default_switch_case(); + } else { + phpdbg_dump_backtrace(param->num TSRMLS_CC); } return SUCCESS; @@ -690,44 +697,42 @@ PHPDBG_COMMAND(back) /* {{{ */ PHPDBG_COMMAND(print) /* {{{ */ { - if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln(SEPARATE); - phpdbg_notice("Execution Context Information"); + phpdbg_writeln(SEPARATE); + phpdbg_notice("Execution Context Information"); #ifdef HAVE_LIBREADLINE - phpdbg_writeln("Readline\tyes"); + phpdbg_writeln("Readline\tyes"); #else - phpdbg_writeln("Readline\tno"); + phpdbg_writeln("Readline\tno"); #endif - phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); - phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); - phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); - phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); + phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none"); + phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no"); + phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); + phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); + phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off"); - if (PHPDBG_G(ops)) { - phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); + if (PHPDBG_G(ops)) { + phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last); - if (PHPDBG_G(ops)->last_var) { - phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); - } else { - phpdbg_writeln("Variables\tNone"); - } + if (PHPDBG_G(ops)->last_var) { + phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1); + } else { + phpdbg_writeln("Variables\tNone"); } - - phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); - if (EG(in_execution)) { - phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); - } - - phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); - phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); - phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); - phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); - - phpdbg_writeln(SEPARATE); } + phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no"); + if (EG(in_execution)) { + phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret)); + } + + phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table))); + phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); + phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); + phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); + + phpdbg_writeln(SEPARATE); + return SUCCESS; } /* }}} */ @@ -749,7 +754,7 @@ PHPDBG_COMMAND(set) /* {{{ */ PHPDBG_COMMAND(break) /* {{{ */ { - if (!param || param->type == EMPTY_PARAM) { + if (!param) { phpdbg_set_breakpoint_file( zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); @@ -817,62 +822,38 @@ PHPDBG_COMMAND(shell) /* {{{ */ PHPDBG_COMMAND(source) /* {{{ */ { - /* - switch (param->type) { - case STR_PARAM: { - if (input->argc > 2) { - if (phpdbg_argv_is(1, "export")) { - FILE *h = VCWD_FOPEN(input->argv[2]->string, "w+"); - if (h) { - phpdbg_export_breakpoints(h TSRMLS_CC); - fclose(h); - } else phpdbg_error("Failed to open %s", input->argv[1]->string); - } else { - phpdbg_error( - "Incorrect usage of source command, see help"); - } - } else { - struct stat sb; - if (VCWD_STAT(param->str, &sb) != -1) { - phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); - } else phpdbg_error("Cannot stat %s", param->str); - } - } break; - - phpdbg_default_switch_case(); - }*/ + struct stat sb; + + if (VCWD_STAT(param->str, &sb) != -1) { + phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); + } else phpdbg_error("Cannot stat %s", param->str); + return SUCCESS; } /* }}} */ PHPDBG_COMMAND(register) /* {{{ */ { - switch (param->type) { - case STR_PARAM: { - zend_function *function; - char *lcname = zend_str_tolower_dup(param->str, param->len); - size_t lcname_len = strlen(lcname); + zend_function *function; + char *lcname = zend_str_tolower_dup(param->str, param->len); + size_t lcname_len = strlen(lcname); - if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) { - if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) { - zend_hash_update( - &PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL); - function_add_ref(function); + if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) { + if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) { + zend_hash_update( + &PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL); + function_add_ref(function); - phpdbg_notice( - "Registered %s", lcname); - } else { - phpdbg_error("The requested function (%s) could not be found", param->str); - } - } else { - phpdbg_error( - "The requested name (%s) is already in use", lcname); - } - - efree(lcname); - } break; - - phpdbg_default_switch_case(); + phpdbg_notice( + "Registered %s", lcname); + } else { + phpdbg_error("The requested function (%s) could not be found", param->str); + } + } else { + phpdbg_error( + "The requested name (%s) is already in use", lcname); } + + efree(lcname); return SUCCESS; } /* }}} */ @@ -926,7 +907,7 @@ PHPDBG_COMMAND(clear) /* {{{ */ PHPDBG_COMMAND(list) /* {{{ */ { - if (!param || param->type == EMPTY_PARAM) { + if (!param) { return PHPDBG_LIST_HANDLER(lines)(PHPDBG_COMMAND_ARGS); } else switch (param->type) { case NUMERIC_PARAM: @@ -978,11 +959,11 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ switch (ret = phpdbg_stack_execute(&stack, &why)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - /*if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { - - }*/ - phpdbg_error("%s", why); + if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_error("%s", why); + } } + if (why) { free(why); why = NULL; From e37144f44b4f5d7869f84a6ba1ed3891d07d0708 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 20:46:56 +0000 Subject: [PATCH 073/137] moar cleanup --- phpdbg_list.c | 75 +++++++++-------------- phpdbg_print.c | 160 ++++++++++++++++++++++--------------------------- 2 files changed, 99 insertions(+), 136 deletions(-) diff --git a/phpdbg_list.c b/phpdbg_list.c index 60377142925..37c0851f77c 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -71,41 +71,28 @@ PHPDBG_LIST(lines) /* {{{ */ PHPDBG_LIST(func) /* {{{ */ { - switch (param->type) { - case STR_PARAM: - phpdbg_list_function_byname( - param->str, param->len TSRMLS_CC); - break; - - phpdbg_default_switch_case(); - } + phpdbg_list_function_byname(param->str, param->len TSRMLS_CC); return SUCCESS; } /* }}} */ PHPDBG_LIST(method) /* {{{ */ { - switch (param->type) { - case METHOD_PARAM: { - zend_class_entry **ce; + zend_class_entry **ce; - if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { - zend_function *function; - char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); + if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + zend_function *function; + char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); - if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) { - phpdbg_list_function(function TSRMLS_CC); - } else { - phpdbg_error("Could not find %s::%s", param->method.class, param->method.name); - } + if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) { + phpdbg_list_function(function TSRMLS_CC); + } else { + phpdbg_error("Could not find %s::%s", param->method.class, param->method.name); + } - efree(lcname); - } else { - phpdbg_error("Could not find the class %s", param->method.class); - } - } break; - - phpdbg_default_switch_case(); + efree(lcname); + } else { + phpdbg_error("Could not find the class %s", param->method.class); } return SUCCESS; @@ -113,30 +100,24 @@ PHPDBG_LIST(method) /* {{{ */ PHPDBG_LIST(class) /* {{{ */ { - switch (param->type) { - case STR_PARAM: { - zend_class_entry **ce; + zend_class_entry **ce; - if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { - if ((*ce)->type == ZEND_USER_CLASS) { - if ((*ce)->info.user.filename) { - phpdbg_list_file( - (*ce)->info.user.filename, - (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1, - (*ce)->info.user.line_start, 0 TSRMLS_CC - ); - } else { - phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name); - } - } else { - phpdbg_error("The class requested (%s) is not user defined", (*ce)->name); - } + if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + if ((*ce)->type == ZEND_USER_CLASS) { + if ((*ce)->info.user.filename) { + phpdbg_list_file( + (*ce)->info.user.filename, + (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1, + (*ce)->info.user.line_start, 0 TSRMLS_CC + ); } else { - phpdbg_error("The requested class (%s) could not be found", param->str); + phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name); } - } break; - - phpdbg_default_switch_case(); + } else { + phpdbg_error("The class requested (%s) is not user defined", (*ce)->name); + } + } else { + phpdbg_error("The requested class (%s) could not be found", param->str); } return SUCCESS; diff --git a/phpdbg_print.c b/phpdbg_print.c index c0265d60cf2..76321a5042d 100644 --- a/phpdbg_print.c +++ b/phpdbg_print.c @@ -154,36 +154,30 @@ PHPDBG_PRINT(class) /* {{{ */ { zend_class_entry **ce; - switch (param->type) { - case STR_PARAM: { - if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { - phpdbg_notice("%s %s: %s", - ((*ce)->type == ZEND_USER_CLASS) ? - "User" : "Internal", - ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? - "Interface" : - ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? - "Abstract Class" : - "Class", - (*ce)->name); + if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) { + phpdbg_notice("%s %s: %s", + ((*ce)->type == ZEND_USER_CLASS) ? + "User" : "Internal", + ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ? + "Interface" : + ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ? + "Abstract Class" : + "Class", + (*ce)->name); - phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table)); - if (zend_hash_num_elements(&(*ce)->function_table)) { - HashPosition position; - zend_function *method; + phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table)); + if (zend_hash_num_elements(&(*ce)->function_table)) { + HashPosition position; + zend_function *method; - for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position); - zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS; - zend_hash_move_forward_ex(&(*ce)->function_table, &position)) { - phpdbg_print_function_helper(method TSRMLS_CC); - } - } - } else { - phpdbg_error("The class %s could not be found", param->str); + for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position); + zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS; + zend_hash_move_forward_ex(&(*ce)->function_table, &position)) { + phpdbg_print_function_helper(method TSRMLS_CC); } - } break; - - phpdbg_default_switch_case(); + } + } else { + phpdbg_error("The class %s could not be found", param->str); } return SUCCESS; @@ -191,31 +185,25 @@ PHPDBG_PRINT(class) /* {{{ */ PHPDBG_PRINT(method) /* {{{ */ { - switch (param->type) { - case METHOD_PARAM: { - zend_class_entry **ce; + zend_class_entry **ce; - if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { - zend_function *fbc; - char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); + if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) { + zend_function *fbc; + char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name)); - if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("%s Method %s", - (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", - fbc->common.function_name); + if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { + phpdbg_notice("%s Method %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + fbc->common.function_name); - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The method %s could not be found", param->method.name); - } + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The method %s could not be found", param->method.name); + } - efree(lcname); - } else { - phpdbg_error("The class %s could not be found", param->method.class); - } - } break; - - phpdbg_default_switch_case(); + efree(lcname); + } else { + phpdbg_error("The class %s could not be found", param->method.class); } return SUCCESS; @@ -223,49 +211,43 @@ PHPDBG_PRINT(method) /* {{{ */ PHPDBG_PRINT(func) /* {{{ */ { - switch (param->type) { - case STR_PARAM: { - HashTable *func_table = EG(function_table); - zend_function* fbc; - const char *func_name = param->str; - size_t func_name_len = param->len; - char *lcname; - /* search active scope if begins with period */ - if (func_name[0] == '.') { - if (EG(scope)) { - func_name++; - func_name_len--; + HashTable *func_table = EG(function_table); + zend_function* fbc; + const char *func_name = param->str; + size_t func_name_len = param->len; + char *lcname; + /* search active scope if begins with period */ + if (func_name[0] == '.') { + if (EG(scope)) { + func_name++; + func_name_len--; - func_table = &EG(scope)->function_table; - } else { - phpdbg_error("No active class"); - return SUCCESS; - } - } else if (!EG(function_table)) { - phpdbg_error("No function table loaded"); - return SUCCESS; - } else { - func_table = EG(function_table); - } - - lcname = zend_str_tolower_dup(func_name, func_name_len); - - if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { - phpdbg_notice("%s %s %s", - (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", - (fbc->common.scope) ? "Method" : "Function", - fbc->common.function_name); - - phpdbg_print_function_helper(fbc TSRMLS_CC); - } else { - phpdbg_error("The function %s could not be found", func_name); - } - - efree(lcname); - } break; - - phpdbg_default_switch_case(); + func_table = &EG(scope)->function_table; + } else { + phpdbg_error("No active class"); + return SUCCESS; + } + } else if (!EG(function_table)) { + phpdbg_error("No function table loaded"); + return SUCCESS; + } else { + func_table = EG(function_table); } + lcname = zend_str_tolower_dup(func_name, func_name_len); + + if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) { + phpdbg_notice("%s %s %s", + (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal", + (fbc->common.scope) ? "Method" : "Function", + fbc->common.function_name); + + phpdbg_print_function_helper(fbc TSRMLS_CC); + } else { + phpdbg_error("The function %s could not be found", func_name); + } + + efree(lcname); + return SUCCESS; } /* }}} */ From ee6cc5ba603cfc7204d090a7b93b1cd5094396f4 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 21 Feb 2014 21:31:01 +0000 Subject: [PATCH 074/137] do not allow abbreivation of anything without alias, fixes input for sh/ev --- dev/phpdbg_lexer.l | 4 +- phpdbg_break.c | 4 +- phpdbg_cmd.c | 14 +++-- phpdbg_help.c | 49 +++++++---------- phpdbg_lexer.c | 131 +++++++++++++++++++++------------------------ phpdbg_prompt.c | 96 +++++++++++++++------------------ phpdbg_prompt.h | 4 +- 7 files changed, 141 insertions(+), 161 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 5f4652fc3d3..90f9f0c63aa 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -29,8 +29,8 @@ T_FALSE ?i:"false" T_NO ?i:"no" T_OFF ?i:"off" T_DISABLED ?i:"disabled" -T_EVAL ?i:"eval" -T_SHELL ?i:"shell" +T_EVAL ?i:"ev" +T_SHELL ?i:"sh" T_IF ?i:"if" WS [ \r\n\t]+ diff --git a/phpdbg_break.c b/phpdbg_break.c index 79091d27e67..be76b22b059 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -35,8 +35,8 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); * Commands */ const phpdbg_command_t phpdbg_break_commands[] = { - PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", 'A', break_at, NULL, "*c"), - PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", 'd', break_del, NULL, "n"), + PHPDBG_BREAK_COMMAND_D(at, "specify breakpoint by location and condition", '@', break_at, NULL, "*c"), + PHPDBG_BREAK_COMMAND_D(del, "delete breakpoint by identifier number", '~', break_del, NULL, "n"), PHPDBG_END_COMMAND }; diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 813911d9a3f..814939758aa 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -655,8 +655,14 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * /* match full, case insensitive, command name */ if (strncasecmp(command->name, name->str, name->len) == SUCCESS) { if (matches < 3) { - matched[matches] = command; - matches++; + + /* only allow abbreviating commands that can be aliased */ + if (((name->len != command->name_len) && command->alias) || + (name->len == command->name_len)) { + matched[matches] = command; + matches++; + } + /* exact match */ if (name->len == command->name_len) @@ -748,10 +754,10 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { switch (top->type) { case EVAL_PARAM: - return PHPDBG_COMMAND_HANDLER(eval)(top TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); case SHELL_PARAM: - return PHPDBG_COMMAND_HANDLER(shell)(top TSRMLS_CC); + return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); case STR_PARAM: { handler = phpdbg_stack_resolve( diff --git a/phpdbg_help.c b/phpdbg_help.c index 993a9c99099..e091fb86f6e 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -328,23 +328,23 @@ phpdbg_help_text_t phpdbg_help_text[] = { "**Starting and Stopping Execution**" CR " **exec** set execution context" CR -" **clean** clean the execution environment" CR " **run** attempt execution" CR -" **eval** evaluate some code" CR " **step** Enable or disable per opcode stepping mode" CR " **next** continue execution" CR " **until** continue execution up to the given location" CR " **finish** continue up to end of the current execution frame" CR " **leave** continue up to end of the current execution frame and halt after the calling instruction" CR " **break** set a breakpoint at the specified target" CR -" **clear** clear one or all breakpoints" CR CR +" **ev** evaluate some code" CR +" **clear** clear one or all breakpoints" CR +" **clean** clean the execution environment" CR CR "**Miscellaneous**" CR " **quiet** silence some output" CR " **set** set the phpdbg configuration" CR " **source** execute a phpdbginit script" CR " **register** register a phpdbginit function as a command alias" CR -" **shell** shell a command" CR +" **sh** shell a command" CR " **quit** exit phpdbg" CR CR "Type **help ** or (**help alias**) to get detailed help on any of the above commands, " @@ -416,7 +416,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, {"syntax", CR -"All **phpdbg** commands are case sensitive. Commands start with a keyword, and some (**break**, " +"Commands start with a keyword, and some (**break**, " "**info**, **set**, **print** and **list**) may include a subcommand keyword. All keywords are " "lower case but also have a single letter alias that may be used as an alternative to typing in the" "keyword in full. Note some aliases are uppercase, and that keywords cannot be abbreviated other " @@ -444,27 +444,18 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P q" CR " Quit the debugger" CR CR -" $P eval $total[2]" CR -" $P E $total[2]" CR +" $P ev $total[2]" CR " Evaluate and print the variable $total[2] in the current stack frame" CR " " CR -" $P break lineno 200" CR +" $P break 200" CR " $P b my_source.php:200" CR " Break at line 200 in the current source and in file **my_source.php**. " CR CR -" $P b A ClassX::get_args if $arg[0] == \"fred\"" CR -" $P b d 3" CR +" $P b @ ClassX::get_args if $arg[0] == \"fred\"" CR +" $P b ~ 3" CR " Break at ClassX::get_args() if $arg[0] == \"fred\" and delete breakpoint 3" CR CR "**Examples of invalid commands**" CR -" $P break line 23" CR -" The command keyword is **lineno**; **line** is not allowed" CR CR - -" $P NEXT" CR -" Commands are case sensitive. The keyword is **next**" CR CR - -" $P s on" CR -" **step** takes an integer argument **0** or **1**; on/off is not allowed." CR CR " $P #This is a comment" CR " Comments introduced by the **#** character are only allowed in **phpdbginit** script files." @@ -549,6 +540,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Break when the condition ($cnt > 10) evaluates to true" CR CR " $P break at phpdbg::isGreat if $opt == 'S'" CR +" $P break @ phpdbg::isGreat if $opt == 'S'" CR " Break at any opcode in phpdbg::isGreat when the condition ($opt == 'S') is true" CR CR " $P break at test.php:20 if !isset($x)" CR @@ -559,7 +551,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Break on any occurence of the opcode ZEND_ADD" CR CR " $P break del 2" CR -" $P b d 2" CR +" $P b ~ 2" CR " Remove breakpoint 2" CR CR "Note: Conditional breaks are costly in terms of runtime overhead. Use them only when required " @@ -600,25 +592,23 @@ phpdbg_help_text_t phpdbg_help_text[] = { "to compilation." }, -{"eval", -"The **eval** command takes a string expression which it evaluates and then displays. It " +{"ev", +"The **ev** command takes a string expression which it evaluates and then displays. It " "evaluates in the context of the lowest (that is the executing) frame, unless this has first " "been explicitly changed by issuing a **frame** command. " CR CR "**Examples**" CR CR -" $P eval $variable" CR -" $P E $variable" CR +" $P ev $variable" CR " Will print_r($variable) on the console, if it is defined" CR CR -" $P eval $variable = \"Hello phpdbg :)\"" CR -" $P E $variable = \"Hello phpdbg :)\"" CR +" $P ev $variable = \"Hello phpdbg :)\"" CR " Will set $variable in the current scope" CR CR -"Note that **eval** allows any valid PHP expression including assignments, function calls and " +"Note that **ev** allows any valid PHP expression including assignments, function calls and " "other write statements. This enables you to change the environment during execution, so care " "is needed here. You can even call PHP functions which have breakpoints defined. " CR CR -"Note: **eval** will always show the result, so do not prefix the code with **return**" +"Note: **ev** will always show the result, so do not prefix the code with **return**" }, {"exec", @@ -853,12 +843,11 @@ phpdbg_help_text_t phpdbg_help_text[] = { //*********** check oplog syntax }, -{"shell", +{"sh", "Direct access to shell commands saves having to switch windows/consoles" CR CR "**Examples**" CR CR -" $P shell ls /usr/src/php-src" CR -" $P - ls /usr/src/php-src" CR +" $P sh ls /usr/src/php-src" CR " Will execute ls /usr/src/php-src, displaying the output in the console" //*********** what does this mean????Note: read only commands please! }, diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index ba8980c27c6..730c5fb68c1 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -358,16 +358,15 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[72] = +static yyconst flex_int16_t yy_accept[67] = { 0, - 0, 0, 0, 0, 16, 12, 14, 1, 9, 9, + 12, 12, 0, 0, 16, 12, 14, 1, 9, 9, 3, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 12, 14, 9, 12, 2, 12, 12, - 12, 12, 6, 8, 12, 7, 12, 12, 12, 12, - 13, 13, 10, 12, 12, 12, 12, 8, 12, 12, - 7, 12, 12, 12, 4, 12, 12, 7, 12, 12, - 12, 8, 5, 12, 12, 12, 11, 12, 7, 8, - 0 + 4, 12, 6, 8, 12, 7, 5, 12, 12, 12, + 13, 13, 10, 12, 12, 12, 8, 12, 7, 12, + 12, 12, 12, 7, 12, 12, 12, 8, 12, 12, + 12, 11, 12, 7, 8, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -411,31 +410,29 @@ static yyconst flex_int32_t yy_meta[47] = 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[76] = +static yyconst flex_int16_t yy_base[71] = { 0, - 0, 0, 45, 47, 146, 0, 49, 202, 48, 51, - 132, 42, 41, 52, 49, 42, 50, 51, 47, 57, - 58, 0, 70, 0, 72, 86, 90, 202, 54, 79, - 89, 88, 0, 0, 93, 0, 96, 87, 90, 94, - 0, 112, 0, 96, 106, 99, 105, 0, 114, 120, - 0, 122, 127, 120, 0, 126, 123, 0, 82, 124, - 130, 0, 0, 160, 131, 137, 168, 139, 0, 0, - 202, 196, 78, 199, 64 + 0, 0, 45, 47, 148, 0, 49, 184, 48, 51, + 138, 42, 41, 52, 49, 42, 50, 51, 47, 57, + 58, 0, 70, 0, 72, 86, 90, 184, 54, 79, + 0, 80, 0, 0, 91, 0, 0, 83, 87, 91, + 0, 109, 0, 97, 103, 92, 0, 102, 0, 105, + 108, 111, 117, 0, 117, 117, 118, 0, 136, 126, + 128, 150, 132, 0, 0, 184, 178, 78, 181, 64 } ; -static yyconst flex_int16_t yy_def[76] = +static yyconst flex_int16_t yy_def[71] = { 0, - 71, 1, 72, 72, 71, 73, 71, 71, 73, 73, - 71, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 74, 74, 73, 71, 73, 73, 71, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 74, 74, 27, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 73, 75, 73, 73, 75, 73, 73, 73, - 0, 71, 71, 71, 71 + 66, 1, 67, 67, 66, 68, 66, 66, 68, 68, + 66, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 69, 69, 68, 66, 68, 68, 66, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 69, 69, 27, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 70, 68, + 68, 70, 68, 68, 68, 0, 66, 66, 66, 66 } ; -static yyconst flex_int16_t yy_nxt[249] = +static yyconst flex_int16_t yy_nxt[231] = { 0, 6, 7, 7, 8, 9, 10, 9, 11, 6, 6, 6, 12, 13, 14, 6, 6, 15, 6, 16, 17, @@ -443,30 +440,28 @@ static yyconst flex_int16_t yy_nxt[249] = 12, 13, 14, 6, 15, 6, 16, 17, 6, 18, 19, 6, 6, 6, 20, 21, 23, 7, 23, 7, 25, 25, 26, 26, 26, 26, 26, 26, 29, 30, - 32, 34, 33, 35, 67, 31, 37, 38, 36, 39, + 32, 34, 33, 35, 62, 31, 37, 38, 36, 39, 40, 42, 25, 25, 25, 44, 29, 30, 24, 34, 32, 33, 35, 31, 37, 38, 36, 45, 39, 40, 26, 26, 26, 44, 27, 43, 43, 46, 43, 43, - 43, 43, 43, 43, 53, 47, 48, 45, 49, 64, - 50, 51, 52, 42, 25, 54, 55, 46, 43, 43, - 43, 43, 43, 47, 53, 48, 56, 49, 50, 51, - 52, 57, 58, 59, 55, 54, 60, 61, 62, 28, - 63, 65, 66, 68, 56, 71, 71, 71, 69, 57, - 70, 58, 59, 71, 71, 61, 60, 62, 63, 65, - 24, 66, 68, 71, 24, 24, 24, 69, 24, 70, - 71, 71, 24, 24, 24, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 24, 71, 71, - 71, 71, 71, 71, 71, 24, 22, 22, 22, 41, + 43, 43, 43, 43, 47, 51, 48, 45, 49, 50, + 42, 25, 52, 53, 54, 46, 55, 56, 43, 43, + 43, 43, 43, 47, 48, 51, 49, 50, 57, 58, + 61, 53, 52, 54, 60, 55, 24, 56, 63, 64, + 24, 24, 24, 65, 59, 28, 57, 66, 58, 61, + 24, 66, 60, 66, 24, 24, 24, 63, 64, 66, + 66, 66, 65, 24, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 24, 22, 22, + 22, 41, 41, 5, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 41, 5, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71 + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66 } ; -static yyconst flex_int16_t yy_chk[249] = +static yyconst flex_int16_t yy_chk[231] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -474,27 +469,25 @@ static yyconst flex_int16_t yy_chk[249] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 7, 7, 9, 9, 9, 10, 10, 10, 12, 13, - 14, 16, 15, 17, 75, 13, 18, 19, 17, 20, - 21, 23, 23, 25, 25, 29, 12, 13, 73, 16, + 14, 16, 15, 17, 70, 13, 18, 19, 17, 20, + 21, 23, 23, 25, 25, 29, 12, 13, 68, 16, 14, 15, 17, 13, 18, 19, 17, 30, 20, 21, - 26, 26, 26, 29, 10, 27, 27, 31, 27, 27, + 26, 26, 26, 29, 10, 27, 27, 32, 27, 27, - 27, 27, 27, 27, 44, 32, 35, 30, 37, 59, - 38, 39, 40, 42, 42, 45, 46, 31, 27, 27, - 27, 27, 27, 32, 44, 35, 47, 37, 38, 39, - 40, 49, 50, 52, 46, 45, 53, 54, 56, 11, - 57, 60, 61, 65, 47, 5, 0, 0, 66, 49, - 68, 50, 52, 0, 0, 54, 53, 56, 57, 60, - 64, 61, 65, 0, 64, 64, 64, 66, 67, 68, - 0, 0, 67, 67, 67, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, - 0, 0, 0, 0, 0, 67, 72, 72, 72, 74, + 27, 27, 27, 27, 35, 44, 38, 30, 39, 40, + 42, 42, 45, 46, 48, 32, 50, 51, 27, 27, + 27, 27, 27, 35, 38, 44, 39, 40, 52, 53, + 57, 46, 45, 48, 56, 50, 59, 51, 60, 61, + 59, 59, 59, 63, 55, 11, 52, 5, 53, 57, + 62, 0, 56, 0, 62, 62, 62, 60, 61, 0, + 0, 0, 63, 59, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 62, 67, 67, + 67, 69, 69, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 74, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71 + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66 } ; /* The intent behind this definition is that it'll catch @@ -520,7 +513,7 @@ static yyconst flex_int16_t yy_chk[249] = #include #define YY_NO_UNISTD_H 1 -#line 524 "sapi/phpdbg/phpdbg_lexer.c" +#line 517 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -760,7 +753,7 @@ YY_DECL #line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 764 "sapi/phpdbg/phpdbg_lexer.c" +#line 757 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -815,13 +808,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 67 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 71 ); + while ( yy_current_state != 66 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -962,7 +955,7 @@ YY_RULE_SETUP #line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 966 "sapi/phpdbg/phpdbg_lexer.c" +#line 959 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1258,7 +1251,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 67 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1287,11 +1280,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 72 ) + if ( yy_current_state >= 67 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 71); + yy_is_jam = (yy_current_state == 66); return yy_is_jam ? 0 : yy_current_state; } diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 880e58b323b..534d883d9c9 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -47,7 +47,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, 0), - PHPDBG_COMMAND_D(eval, "evaluate some code", 'E', NULL, "i"), + PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0), @@ -62,8 +62,8 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"), PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), - PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, "s"), - PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, "i"), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '-', NULL, "s"), + PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -77,13 +77,17 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * if (stack->type == STACK_PARAM) { name = stack->next; + if (!name || name->type != STR_PARAM) { + return FAILURE; + } + if (zend_hash_exists( - &PHPDBG_G(registered), name->str, name->len+1)) { + &PHPDBG_G(registered), name->str, name->len+1)) { zval fname, *fretval; zend_fcall_info fci; - ZVAL_STRINGL(&fname, name->str, name->len, 1); + ZVAL_STRINGL(&fname, name->str, name->len+1, 1); memset(&fci, 0, sizeof(zend_fcall_info)); @@ -640,42 +644,36 @@ out: return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(eval) /* {{{ */ +PHPDBG_COMMAND(ev) /* {{{ */ { - switch (param->type) { - case EVAL_PARAM: { - zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); - zval retval; + zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)==PHPDBG_IS_STEPPING); + zval retval; - if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { - PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; - } - - /* disable stepping while eval() in progress */ - PHPDBG_G(flags) |= PHPDBG_IN_EVAL; - zend_try { - if (zend_eval_stringl(param->str, param->len, - &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { - zend_print_zval_r( - &retval, 0 TSRMLS_CC); - phpdbg_writeln(EMPTY); - zval_dtor(&retval); - } - } zend_end_try(); - PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; - - /* switch stepping back on */ - if (stepping && - !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - } - - CG(unclean_shutdown) = 0; - } break; - - phpdbg_default_switch_case(); + if (!(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; } + /* disable stepping while eval() in progress */ + PHPDBG_G(flags) |= PHPDBG_IN_EVAL; + zend_try { + if (zend_eval_stringl(param->str, param->len, + &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { + zend_print_zval_r( + &retval, 0 TSRMLS_CC); + phpdbg_writeln(EMPTY); + zval_dtor(&retval); + } + } zend_end_try(); + PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; + + /* switch stepping back on */ + if (stepping && + !(PHPDBG_G(flags) & PHPDBG_IS_STEPONEVAL)) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } + + CG(unclean_shutdown) = 0; + return SUCCESS; } /* }}} */ @@ -800,23 +798,17 @@ PHPDBG_COMMAND(break) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(shell) /* {{{ */ +PHPDBG_COMMAND(sh) /* {{{ */ { - /* don't allow this to loop, ever ... */ - switch (param->type) { - case SHELL_PARAM: { - FILE *fd = NULL; - if ((fd=VCWD_POPEN((char*)param->str, "w"))) { - /* do something perhaps ?? do we want input ?? */ - fclose(fd); - } else { - phpdbg_error( - "Failed to execute %s", param->str); - } - } break; - - phpdbg_default_switch_case(); + FILE *fd = NULL; + if ((fd=VCWD_POPEN((char*)param->str, "w"))) { + /* do something perhaps ?? do we want input ?? */ + fclose(fd); + } else { + phpdbg_error( + "Failed to execute %s", param->str); } + return SUCCESS; } /* }}} */ diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index d92623d409c..5590dd41219 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -34,7 +34,7 @@ PHPDBG_COMMAND(compile); PHPDBG_COMMAND(step); PHPDBG_COMMAND(next); PHPDBG_COMMAND(run); -PHPDBG_COMMAND(eval); +PHPDBG_COMMAND(ev); PHPDBG_COMMAND(until); PHPDBG_COMMAND(finish); PHPDBG_COMMAND(leave); @@ -47,7 +47,7 @@ PHPDBG_COMMAND(info); PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clear); PHPDBG_COMMAND(help); -PHPDBG_COMMAND(shell); +PHPDBG_COMMAND(sh); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); PHPDBG_COMMAND(register); From 4b738cee2b789228b34bc5ef0f246e325890fd78 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 23 Feb 2014 07:33:48 +0000 Subject: [PATCH 075/137] set colors working --- phpdbg_cmd.c | 30 ++++++++++++--------- phpdbg_help.c | 3 +-- phpdbg_lexer.c | 2 +- phpdbg_prompt.c | 18 ++++++++----- phpdbg_set.c | 72 ++++++++++++++++++++++++------------------------- phpdbg_utils.c | 23 ++++++++++++++++ phpdbg_utils.h | 22 +++++++++++---- 7 files changed, 107 insertions(+), 63 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 814939758aa..a71c3969458 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -551,7 +551,7 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param } asprintf(why, - "%s expected no arguments", + "The command \"%s\" expected no arguments", phpdbg_command_name(command, buffer)); return FAILURE; } @@ -572,7 +572,7 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param #define verify_arg(e, a, t) if (!(a)) { \ if (!optional) { \ asprintf(why, \ - "%s expected %s and got nothing at parameter %lu", \ + "The command \"%s\" expected %s and got nothing at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e), \ current); \ @@ -580,7 +580,7 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param } \ } else if ((a)->type != (t)) { \ asprintf(why, \ - "%s expected %s and got %s at parameter %lu", \ + "The command \"%s\" expected %s and got %s at parameter %lu", \ phpdbg_command_name(command, buffer), \ (e),\ phpdbg_get_param_type((a) TSRMLS_CC), \ @@ -623,7 +623,7 @@ PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param if ((received < least)) { asprintf(why, - "%s expected at least %lu arguments (%s) and received %lu", + "The command \"%s\" expected at least %lu arguments (%s) and received %lu", phpdbg_command_name(command, buffer), least, command->args, @@ -676,13 +676,17 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } switch (matches) { - case 0: if (!parent) { - asprintf( + case 0: { + if (parent) { + asprintf( why, - "The command %s could not be found", + "The command \"%s %s\" could not be found", + parent->name, name->str); + } else asprintf( + why, + "The command \"%s\" could not be found", name->str); - return NULL; - } else return parent; + } return parent; case 1: { (*top) = (*top)->next; @@ -718,7 +722,7 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * asprintf( why, - "The command %s is ambigious, matching %lu commands (%s)", + "The command \"%s\" is ambigious, matching %lu commands (%s)", name->str, matches, list); free(list); } return NULL; @@ -740,13 +744,13 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { if (stack->type != STACK_PARAM) { asprintf( - why, "the passed argument was not a stack !!"); + why, "The passed argument was not a stack !!"); return FAILURE; } if (!stack->len) { asprintf( - why, "the stack contains nothing !!"); + why, "The stack contains nothing !!"); return FAILURE; } @@ -772,7 +776,7 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { default: asprintf( - why, "the first parameter makes no sense !!"); + why, "The first parameter makes no sense !!"); return FAILURE; } diff --git a/phpdbg_help.c b/phpdbg_help.c index e091fb86f6e..1796db7f60f 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -248,8 +248,7 @@ PHPDBG_COMMAND(help) /* {{{ */ } } } - - phpdbg_error("No help can be found for the subject \"%s\"", param->str); + return FAILURE; } /* }}} */ diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 730c5fb68c1..1feed66ab9b 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -360,7 +360,7 @@ struct yy_trans_info }; static yyconst flex_int16_t yy_accept[67] = { 0, - 12, 12, 0, 0, 16, 12, 14, 1, 9, 9, + 0, 0, 0, 0, 16, 12, 14, 1, 9, 9, 3, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 12, 14, 9, 12, 2, 12, 12, 4, 12, 6, 8, 12, 7, 5, 12, 12, 12, diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 534d883d9c9..c733117b75b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -745,7 +745,7 @@ PHPDBG_COMMAND(info) /* {{{ */ PHPDBG_COMMAND(set) /* {{{ */ { phpdbg_error( - "No information command selected!"); + "No set command selected!"); return SUCCESS; } /* }}} */ @@ -952,7 +952,9 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - phpdbg_error("%s", why); + if (why) { + phpdbg_error("%s", why); + } } } @@ -973,18 +975,18 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } } } - + if (why) { free(why); why = NULL; } - + yy_delete_buffer(state, scanner); yylex_destroy(scanner); - + phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); - + } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); if (!input) @@ -1003,6 +1005,10 @@ out: if (input) { phpdbg_destroy_input(&input TSRMLS_CC); } + + if (why) { + free(why); + } phpdbg_stack_free(&stack); diff --git a/phpdbg_set.c b/phpdbg_set.c index 739acd3c714..fa462e2f182 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -102,43 +102,43 @@ PHPDBG_SET(breaks) /* {{{ */ #ifndef _WIN32 PHPDBG_SET(color) /* {{{ */ { - /*if ((param->type == STR_PARAM) && (input->argc == 3)) { - const phpdbg_color_t *color = phpdbg_get_color( - input->argv[2]->string, input->argv[2]->length TSRMLS_CC); - int element = PHPDBG_COLOR_INVALID; - - if (color) { - if (phpdbg_argv_is(1, "prompt")) { - phpdbg_notice( - "setting prompt color to %s (%s)", color->name, color->code); - element = PHPDBG_COLOR_PROMPT; - if (PHPDBG_G(prompt)[1]) { - free(PHPDBG_G(prompt)[1]); - PHPDBG_G(prompt)[1]=NULL; - } - } else if (phpdbg_argv_is(1, "error")) { - phpdbg_notice( - "setting error color to %s (%s)", color->name, color->code); - element = PHPDBG_COLOR_ERROR; - - } else if (phpdbg_argv_is(1, "notice")) { - phpdbg_notice( - "setting notice color to %s (%s)", color->name, color->code); - element = PHPDBG_COLOR_NOTICE; - - } else goto usage; - - phpdbg_set_color(element, color TSRMLS_CC); - } else { - phpdbg_error( - "Failed to find the requested color (%s)", input->argv[2]->string); - } - } else { -usage: - phpdbg_error( - "set color used incorrectly: set color "); - } */ + const phpdbg_color_t *color = phpdbg_get_color( + param->next->str, param->next->len TSRMLS_CC); + if (!color) { + phpdbg_error( + "Failed to find the requested color (%s)", param->next->str); + return SUCCESS; + } + + switch (phpdbg_get_element(param->str, param->len TSRMLS_CC)) { + case PHPDBG_COLOR_PROMPT: + phpdbg_notice( + "setting prompt color to %s (%s)", color->name, color->code); + if (PHPDBG_G(prompt)[1]) { + free(PHPDBG_G(prompt)[1]); + PHPDBG_G(prompt)[1]=NULL; + } + phpdbg_set_color(PHPDBG_COLOR_PROMPT, color TSRMLS_CC); + break; + + case PHPDBG_COLOR_ERROR: + phpdbg_notice( + "setting error color to %s (%s)", color->name, color->code); + phpdbg_set_color(PHPDBG_COLOR_ERROR, color TSRMLS_CC); + break; + + case PHPDBG_COLOR_NOTICE: + phpdbg_notice( + "setting notice color to %s (%s)", color->name, color->code); + phpdbg_set_color(PHPDBG_COLOR_NOTICE, color TSRMLS_CC); + break; + + default: + phpdbg_error( + "Failed to find the requested element (%s)", param->str); + } + return SUCCESS; } /* }}} */ diff --git a/phpdbg_utils.c b/phpdbg_utils.c index d64d9ad6860..b32fce34783 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -67,6 +67,14 @@ const static phpdbg_color_t colors[] = { PHPDBG_COLOR_END }; /* }}} */ +/* {{{ */ +const static phpdbg_element_t elements[] = { + PHPDBG_ELEMENT_D("prompt", PHPDBG_COLOR_PROMPT), + PHPDBG_ELEMENT_D("error", PHPDBG_COLOR_ERROR), + PHPDBG_ELEMENT_D("notice", PHPDBG_COLOR_NOTICE), + PHPDBG_ELEMENT_END +}; /* }}} */ + PHPDBG_API int phpdbg_is_numeric(const char *str) /* {{{ */ { if (!str) @@ -349,6 +357,21 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */ return colors; } /* }}} */ +PHPDBG_API int phpdbg_get_element(const char *name, size_t len) { + const phpdbg_element_t *element = elements; + + while (element && element->name) { + if (len == element->name_length) { + if (strncasecmp(name, element->name, len) == SUCCESS) { + return element->id; + } + } + element++; + } + + return PHPDBG_COLOR_INVALID; +} + PHPDBG_API void phpdbg_set_prompt(const char *prompt TSRMLS_DC) /* {{{ */ { /* free formatted prompt */ diff --git a/phpdbg_utils.h b/phpdbg_utils.h index ee7ff3f5bd1..f2be63be104 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -85,12 +85,17 @@ PHPDBG_API int phpdbg_rlog(FILE *stream, const char *fmt, ...); {color, sizeof(color)-1, code} #define PHPDBG_COLOR_END \ {NULL, 0L, {0}} +#define PHPDBG_ELEMENT_LEN 3 +#define PHPDBG_ELEMENT_D(name, id) \ + {name, sizeof(name)-1, id} +#define PHPDBG_ELEMENT_END \ + {NULL, 0L, 0} #define PHPDBG_COLOR_INVALID -1 -#define PHPDBG_COLOR_PROMPT 0 -#define PHPDBG_COLOR_ERROR 1 -#define PHPDBG_COLOR_NOTICE 2 -#define PHPDBG_COLORS 3 +#define PHPDBG_COLOR_PROMPT 0 +#define PHPDBG_COLOR_ERROR 1 +#define PHPDBG_COLOR_NOTICE 2 +#define PHPDBG_COLORS 3 typedef struct _phpdbg_color_t { char *name; @@ -98,10 +103,17 @@ typedef struct _phpdbg_color_t { const char code[PHPDBG_COLOR_LEN]; } phpdbg_color_t; +typedef struct _phpdbg_element_t { + char *name; + size_t name_length; + int id; +} phpdbg_element_t; + PHPDBG_API const phpdbg_color_t *phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC); PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC); PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC); -PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); /* }}} */ +PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D); +PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC); /* }}} */ /* {{{ Prompt Management */ PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC); From 85b5907e85441a4fdccdd8978d29084f72c20f4f Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 24 Feb 2014 09:26:03 +0000 Subject: [PATCH 076/137] fix ts build --- dev/phpdbg_parser.y | 1 + phpdbg_bp.c | 2 +- phpdbg_cmd.c | 4 +- phpdbg_cmd.h | 2 +- phpdbg_lexer.c | 64 ++++---- phpdbg_lexer.h | 15 +- phpdbg_parser.c | 369 +++++++++++++++++++++----------------------- phpdbg_parser.h | 39 +++-- phpdbg_prompt.c | 4 +- phpdbg_utils.c | 2 +- 10 files changed, 253 insertions(+), 249 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index a524352e2a3..37ecb9e8600 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -22,6 +22,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { + TSRMLS_FETCH(); phpdbg_error("Parse Error: %s", msg); { const phpdbg_param_t *top = stack; diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 1d446fae73e..e3e9b8f2451 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -994,7 +994,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut zend_try { PHPDBG_G(flags) |= PHPDBG_IN_COND_BP; zend_execute(EG(active_op_array) TSRMLS_CC); -#if PHP_VERSION_ID >= 50700 +#if PHP_VERSION_ID >= 50600 if (zend_is_true(retval TSRMLS_CC)) { #else if (zend_is_true(retval)) { diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index a71c3969458..cc597f13eec 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -738,7 +738,7 @@ PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t * } /* }}} */ /* {{{ */ -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) { phpdbg_param_t *top = NULL; const phpdbg_command_t *handler = NULL; @@ -768,7 +768,7 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why) { phpdbg_prompt_commands, NULL, &top, why); if (handler) { - if (phpdbg_stack_verify(handler, &top, why) == SUCCESS) { + if (phpdbg_stack_verify(handler, &top, why TSRMLS_CC) == SUCCESS) { return handler->handler(top TSRMLS_CC); } } diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 8028d7ddbc3..af93ba54d4b 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -134,7 +134,7 @@ PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param); PHPDBG_API const phpdbg_command_t* phpdbg_stack_resolve(const phpdbg_command_t *commands, const phpdbg_command_t *parent, phpdbg_param_t **top, char **why); PHPDBG_API int phpdbg_stack_verify(const phpdbg_command_t *command, phpdbg_param_t **stack, char **why TSRMLS_DC); -PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why); +PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC); PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack); /* diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 1feed66ab9b..841f9b24441 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -9,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -54,7 +54,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -170,6 +171,11 @@ typedef void* yyscan_t; typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 @@ -192,11 +198,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state @@ -214,7 +215,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -293,7 +294,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); void *yyalloc (yy_size_t ,yyscan_t yyscanner ); void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); @@ -325,7 +326,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap(yyscanner) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -513,7 +514,7 @@ static yyconst flex_int16_t yy_chk[231] = #include #define YY_NO_UNISTD_H 1 -#line 517 "sapi/phpdbg/phpdbg_lexer.c" +#line 518 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -543,8 +544,8 @@ struct yyguts_t size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; - int yy_n_chars; - int yyleng_r; + yy_size_t yy_n_chars; + yy_size_t yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; @@ -597,7 +598,7 @@ FILE *yyget_out (yyscan_t yyscanner ); void yyset_out (FILE * out_str ,yyscan_t yyscanner ); -int yyget_leng (yyscan_t yyscanner ); +yy_size_t yyget_leng (yyscan_t yyscanner ); char *yyget_text (yyscan_t yyscanner ); @@ -666,7 +667,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - unsigned n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -753,7 +754,7 @@ YY_DECL #line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 757 "sapi/phpdbg/phpdbg_lexer.c" +#line 758 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -955,7 +956,7 @@ YY_RULE_SETUP #line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 959 "sapi/phpdbg/phpdbg_lexer.c" +#line 960 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1144,21 +1145,21 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { - int num_to_read = + yy_size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { - int new_size = b->yy_buf_size * 2; + yy_size_t new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; @@ -1189,7 +1190,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); + yyg->yy_n_chars, num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } @@ -1286,6 +1287,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 66); + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } @@ -1302,7 +1304,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yyg->yy_n_chars + 2; + register yy_size_t number_to_move = yyg->yy_n_chars + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = @@ -1352,7 +1354,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) else { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) @@ -1632,7 +1634,7 @@ void yypop_buffer_state (yyscan_t yyscanner) */ static void yyensure_buffer_stack (yyscan_t yyscanner) { - int num_to_alloc; + yy_size_t num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { @@ -1725,17 +1727,17 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; - int i; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -1845,7 +1847,7 @@ FILE *yyget_out (yyscan_t yyscanner) /** Get the length of the current token. * @param yyscanner The scanner object. */ -int yyget_leng (yyscan_t yyscanner) +yy_size_t yyget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; @@ -1881,7 +1883,7 @@ void yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = line_number; } @@ -1896,7 +1898,7 @@ void yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_column called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = column_no; } diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index b86554c3804..88aef381a17 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -13,7 +13,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -58,7 +58,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -89,6 +88,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -161,7 +162,7 @@ struct yy_buffer_state /* Number of characters read into yy_ch_buf, not including EOB * characters. */ - int yy_n_chars; + yy_size_t yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to @@ -205,7 +206,7 @@ void yypop_buffer_state (yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner ); void *yyalloc (yy_size_t ,yyscan_t yyscanner ); void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); @@ -213,7 +214,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap(yyscanner) 1 #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r @@ -261,7 +262,7 @@ FILE *yyget_out (yyscan_t yyscanner ); void yyset_out (FILE * out_str ,yyscan_t yyscanner ); -int yyget_leng (yyscan_t yyscanner ); +yy_size_t yyget_leng (yyscan_t yyscanner ); char *yyget_text (yyscan_t yyscanner ); @@ -341,6 +342,6 @@ extern int yylex \ #line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 345 "sapi/phpdbg/phpdbg_lexer.h" +#line 346 "sapi/phpdbg/phpdbg_lexer.h" #undef yyIN_HEADER #endif /* yyHEADER_H */ diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 4a0695d1a26..1f6a1515876 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 2.7. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.5" +#define YYBISON_VERSION "2.7" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -58,14 +58,11 @@ /* Pull parsers. */ #define YYPULL 1 -/* Using locations. */ -#define YYLSP_NEEDED 0 /* Copy the first part of user declarations. */ - -/* Line 268 of yacc.c */ +/* Line 371 of yacc.c */ #line 2 "sapi/phpdbg/dev/phpdbg_parser.y" @@ -90,6 +87,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { + TSRMLS_FETCH(); phpdbg_error("Parse Error: %s", msg); { const phpdbg_param_t *top = stack; @@ -103,14 +101,16 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { } } +/* Line 371 of yacc.c */ +#line 106 "sapi/phpdbg/phpdbg_parser.c" -/* Line 268 of yacc.c */ -#line 109 "sapi/phpdbg/phpdbg_parser.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif +# ifndef YY_NULL +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULL nullptr +# else +# define YY_NULL 0 +# endif +# endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE @@ -120,15 +120,20 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { # define YYERROR_VERBOSE 1 #endif -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 +/* In a future release of Bison, this section will be replaced + by #include "phpdbg_parser.h". */ +#ifndef YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +# define YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; #endif - /* "%code requires" blocks. */ - -/* Line 288 of yacc.c */ -#line 39 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 387 of yacc.c */ +#line 40 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -137,9 +142,8 @@ typedef void* yyscan_t; #endif - -/* Line 288 of yacc.c */ -#line 143 "sapi/phpdbg/phpdbg_parser.c" +/* Line 387 of yacc.c */ +#line 147 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -167,7 +171,6 @@ typedef void* yyscan_t; #endif - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -176,11 +179,26 @@ typedef int YYSTYPE; #endif +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (phpdbg_param_t *stack, yyscan_t scanner); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + +#endif /* !YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ + /* Copy the second part of user declarations. */ - -/* Line 343 of yacc.c */ -#line 184 "sapi/phpdbg/phpdbg_parser.c" +/* Line 390 of yacc.c */ +#line 202 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -233,24 +251,24 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint -# define YYID(n) (n) +# define YYID(N) (N) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -286,6 +304,7 @@ YYID (yyi) # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) # include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif @@ -377,20 +396,20 @@ union yyalloc #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from FROM to TO. The source and destination do +/* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) # else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ while (YYID (0)) # endif # endif @@ -474,13 +493,13 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 74, 74, 75, 79, 80, 84, 89, 94, 99, - 105, 111, 116, 121, 126, 127, 128, 129, 130, 131, - 132 + 0, 75, 75, 76, 80, 81, 85, 90, 95, 100, + 106, 112, 117, 122, 127, 128, 129, 130, 131, 132, + 133 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +#if YYDEBUG || YYERROR_VERBOSE || 1 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -493,7 +512,7 @@ static const char *const yytname[] = "\"literal (string)\"", "\"address\"", "\"opcode\"", "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", - "parameters", "parameter", 0 + "parameters", "parameter", YY_NULL }; #endif @@ -566,10 +585,10 @@ static const yytype_uint8 yytable[] = 24, 26, 27, 0, 28, 21 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-10)) +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-10))) -#define yytable_value_is_error(yytable_value) \ +#define yytable_value_is_error(Yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = @@ -615,62 +634,35 @@ static const yytype_uint8 yystos[] = #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ yyerror (stack, scanner, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (YYID (0)) - +/* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - /* This macro is provided for backward compatibility. */ - #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ - #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else @@ -722,6 +714,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner) yyscan_t scanner; #endif { + FILE *yyo = yyoutput; + YYUSE (yyo); if (!yyvaluep) return; YYUSE (stack); @@ -735,7 +729,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner) switch (yytype) { default: - break; + break; } } @@ -979,12 +973,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = 0; + const char *yyformat = YY_NULL; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1044,11 +1037,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1068,10 +1063,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1135,25 +1132,11 @@ yydestruct (yymsg, yytype, yyvaluep, stack, scanner) { default: - break; + break; } } -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (phpdbg_param_t *stack, yyscan_t scanner); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ /*----------. @@ -1186,8 +1169,31 @@ yyparse (stack, scanner) /* The lookahead symbol. */ int yychar; + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +static YYSTYPE yyval_default; +# define YY_INITIAL_VALUE(Value) = Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + /* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; +YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); /* Number of syntax errors so far. */ int yynerrs; @@ -1200,7 +1206,7 @@ YYSTYPE yylval; `yyss': related to states. `yyvs': related to semantic values. - Refer to the stacks thru separate pointers, to allow yyoverflow + Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ @@ -1218,7 +1224,7 @@ YYSTYPE yylval; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ - int yytoken; + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; @@ -1236,9 +1242,8 @@ YYSTYPE yylval; Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -1247,14 +1252,6 @@ YYSTYPE yylval; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - goto yysetstate; /*------------------------------------------------------------. @@ -1395,7 +1392,9 @@ yybackup: yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -1432,23 +1431,20 @@ yyreduce: switch (yyn) { case 4: - -/* Line 1806 of yacc.c */ -#line 79 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } break; case 5: - -/* Line 1806 of yacc.c */ -#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 81 "sapi/phpdbg/dev/phpdbg_parser.y" { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } break; case 6: - -/* Line 1806 of yacc.c */ -#line 84 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 85 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (3)]).str; @@ -1457,9 +1453,8 @@ yyreduce: break; case 7: - -/* Line 1806 of yacc.c */ -#line 89 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 90 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; (yyval).file.name = (yyvsp[(1) - (4)]).str; @@ -1468,9 +1463,8 @@ yyreduce: break; case 8: - -/* Line 1806 of yacc.c */ -#line 94 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 95 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1479,9 +1473,8 @@ yyreduce: break; case 9: - -/* Line 1806 of yacc.c */ -#line 99 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1491,9 +1484,8 @@ yyreduce: break; case 10: - -/* Line 1806 of yacc.c */ -#line 105 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1503,9 +1495,8 @@ yyreduce: break; case 11: - -/* Line 1806 of yacc.c */ -#line 111 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1514,9 +1505,8 @@ yyreduce: break; case 12: - -/* Line 1806 of yacc.c */ -#line 116 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 117 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1525,9 +1515,8 @@ yyreduce: break; case 13: - -/* Line 1806 of yacc.c */ -#line 121 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 1792 of yacc.c */ +#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1536,58 +1525,50 @@ yyreduce: break; case 14: - -/* Line 1806 of yacc.c */ -#line 126 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 15: - -/* Line 1806 of yacc.c */ +/* Line 1792 of yacc.c */ #line 127 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 16: - -/* Line 1806 of yacc.c */ + case 15: +/* Line 1792 of yacc.c */ #line 128 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 17: - -/* Line 1806 of yacc.c */ + case 16: +/* Line 1792 of yacc.c */ #line 129 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 18: - -/* Line 1806 of yacc.c */ + case 17: +/* Line 1792 of yacc.c */ #line 130 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 19: - -/* Line 1806 of yacc.c */ + case 18: +/* Line 1792 of yacc.c */ #line 131 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; - case 20: - -/* Line 1806 of yacc.c */ + case 19: +/* Line 1792 of yacc.c */ #line 132 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; + case 20: +/* Line 1792 of yacc.c */ +#line 133 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; -/* Line 1806 of yacc.c */ -#line 1591 "sapi/phpdbg/phpdbg_parser.c" +/* Line 1792 of yacc.c */ +#line 1572 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1750,7 +1731,9 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -1774,7 +1757,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#if !defined(yyoverflow) || YYERROR_VERBOSE +#if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -1816,8 +1799,6 @@ yyreturn: } - -/* Line 2067 of yacc.c */ -#line 135 "sapi/phpdbg/dev/phpdbg_parser.y" - +/* Line 2055 of yacc.c */ +#line 136 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index 413d3ae192e..a9eea7a56be 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.5. */ +/* A Bison parser, made by GNU Bison 2.7. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,10 +30,18 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ +#ifndef YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +# define YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif /* "%code requires" blocks. */ - -/* Line 2068 of yacc.c */ -#line 39 "sapi/phpdbg/dev/phpdbg_parser.y" +/* Line 2058 of yacc.c */ +#line 40 "sapi/phpdbg/dev/phpdbg_parser.y" #include "phpdbg.h" #ifndef YY_TYPEDEF_YY_SCANNER_T @@ -42,9 +50,8 @@ typedef void* yyscan_t; #endif - -/* Line 2068 of yacc.c */ -#line 48 "sapi/phpdbg/phpdbg_parser.h" +/* Line 2058 of yacc.c */ +#line 55 "sapi/phpdbg/phpdbg_parser.h" /* Tokens. */ #ifndef YYTOKENTYPE @@ -72,7 +79,6 @@ typedef void* yyscan_t; #endif - #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 @@ -81,5 +87,18 @@ typedef int YYSTYPE; #endif +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (phpdbg_param_t *stack, yyscan_t scanner); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ - +#endif /* !YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c733117b75b..09e7ae1ae56 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -230,7 +230,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ state = yy_scan_string(input, scanner); if (yyparse(&stack, scanner) <= 0) { - switch (phpdbg_stack_execute(&stack, &why)) { + switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { @@ -948,7 +948,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ state = yy_scan_string(input, scanner); if (yyparse(&stack, scanner) <= 0) { - switch (ret = phpdbg_stack_execute(&stack, &why)) { + switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c index b32fce34783..23c00158082 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -357,7 +357,7 @@ PHPDBG_API const phpdbg_color_t* phpdbg_get_colors(TSRMLS_D) /* {{{ */ return colors; } /* }}} */ -PHPDBG_API int phpdbg_get_element(const char *name, size_t len) { +PHPDBG_API int phpdbg_get_element(const char *name, size_t len TSRMLS_DC) { const phpdbg_element_t *element = elements; while (element && element->name) { From 043bfd6e2cc8290eeed5aa7a7e2ff0ab4940d42a Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 24 Feb 2014 17:11:09 +0000 Subject: [PATCH 077/137] woops+correction in help --- phpdbg_help.c | 5 ++--- phpdbg_prompt.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 1796db7f60f..47289fb6731 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -398,7 +398,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "overridden on the command line using the **-i** switch (see **help options** for a more " "details)." CR CR -"Debugger scripts can also be executed using the **script** command." CR CR +"Debugger scripts can also be executed using the **source** command." CR CR "A script file can contain a sequence of valid debugger commands, comments and embedded PHP " "code. " CR CR @@ -430,7 +430,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " * **method#op** a valid **Class::methodName** follow by # and an integer" CR " * **string** a general string" CR " * **function** a valid **Function name**" CR -" * **File-line** a valid **filename** follow by : and an integer" CR CR +" * **file:line** a valid **filename** follow by : and an integer" CR CR "In some cases the type of the argument enables the second keyword to be omitted." CR CR @@ -491,7 +491,6 @@ phpdbg_help_text_t phpdbg_help_text[] = { "types:" CR CR " **Target** **Alias** **Purpose**" CR -" **address** **a** specify breakpoint by address" CR " **at** **A** specify breakpoint by location and condition" CR " **del** **d** delete breakpoint by breakpoint identifier number" CR CR diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 09e7ae1ae56..b55e5d7a591 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -87,7 +87,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * zval fname, *fretval; zend_fcall_info fci; - ZVAL_STRINGL(&fname, name->str, name->len+1, 1); + ZVAL_STRINGL(&fname, name->str, name->len, 1); memset(&fci, 0, sizeof(zend_fcall_info)); From 4bab2d2f90022839ffe1262e3e84c3526df4d664 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 24 Feb 2014 19:03:55 +0000 Subject: [PATCH 078/137] export command --- phpdbg_help.c | 16 ++++++++++------ phpdbg_prompt.c | 23 +++++++++++++++++++++-- phpdbg_prompt.h | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 47289fb6731..941d58ce670 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -853,17 +853,21 @@ phpdbg_help_text_t phpdbg_help_text[] = { {"source", "Sourcing a **phpdbginit** script during your debugging session might save some time." CR CR -"The source command can also be used to export breakpoints to a phpdbginit file." CR CR - "**Examples**" CR CR " $P source /my/init" CR -" $P . /my/init" CR +" $P < /my/init" CR " Will execute the phpdbginit file at /my/init" CR CR +}, -" $P source export /my/init" CR -" $P . export /my/init" CR -" Will export breakpoints to /my/init in phpdbginit file format" +{"export", +"Exporting breakpoints allows you to share, and or save your current debugging session" CR CR + +"**Examples**" CR CR + +" $P export /my/exports" CR +" $P > /my/exports" CR +" Will export all breakpoints to /my/exports" CR CR }, {"step", diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index b55e5d7a591..2cae1b6aa96 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -62,7 +62,8 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, "|s"), PHPDBG_COMMAND_D(set, "set phpdbg configuration", 'S', phpdbg_set_commands, "s"), PHPDBG_COMMAND_D(register,"register a function", 'R', NULL, "s"), - PHPDBG_COMMAND_D(source, "execute a phpdbginit", '-', NULL, "s"), + PHPDBG_COMMAND_D(source, "execute a phpdbginit", '<', NULL, "s"), + PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), PHPDBG_END_COMMAND @@ -818,11 +819,29 @@ PHPDBG_COMMAND(source) /* {{{ */ if (VCWD_STAT(param->str, &sb) != -1) { phpdbg_try_file_init(param->str, param->len, 0 TSRMLS_CC); - } else phpdbg_error("Cannot stat %s", param->str); + } else { + phpdbg_error( + "Failed to stat %s, file does not exist", param->str); + } return SUCCESS; } /* }}} */ +PHPDBG_COMMAND(export) /* {{{ */ +{ + FILE *handle = VCWD_FOPEN(param->str, "w+"); + + if (handle) { + phpdbg_export_breakpoints(handle TSRMLS_CC); + fclose(handle); + } else { + phpdbg_error( + "Failed to open or create %s, check path and permissions", param->str); + } + + return SUCCESS; +} /* }}} */ + PHPDBG_COMMAND(register) /* {{{ */ { zend_function *function; diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 5590dd41219..1a48acade37 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -50,6 +50,7 @@ PHPDBG_COMMAND(help); PHPDBG_COMMAND(sh); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); +PHPDBG_COMMAND(export); PHPDBG_COMMAND(register); PHPDBG_COMMAND(quit); /* }}} */ From d8ed537cd4a32d00e1c7b7234619f2232d8df631 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 24 Feb 2014 22:30:46 +0000 Subject: [PATCH 079/137] moar params for registered functions --- dev/phpdbg_lexer.l | 20 ++++++++++++++++++++ phpdbg_prompt.c | 39 +++++++++++++++++++++++++++++++++++---- test.php | 4 ++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index 90f9f0c63aa..d371e59c599 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -11,6 +11,10 @@ #include "phpdbg_parser.h" #include #include + +static inline int phpdbg_needs_params(phpdbg_param_t *param TSRMLS_DC) { + return 0; +} %} %s RAW @@ -40,6 +44,22 @@ ADDR 0x[a-fA-F0-9]+ OPCODE ?i:ZEND_([A-Za-z])+ INPUT [^\n]+ %% +[a-zA-Z]+ { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + if (phpdbg_needs_params(yylval TSRMLS_CC)) { + BEGIN(PARAMS); + } + return T_ID; +} + +[0-9]+ { + phpdbg_init_param(yylval, NUMERIC_PARAM); + yylval->num = atoi(yytext); + return T_ID; +} + { [#]{1} { return T_POUND; } diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 2cae1b6aa96..31c5d251222 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -106,8 +106,12 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * array_init(¶ms); - while (next) { + while (next) { + char *buffered = NULL; + switch (next->type) { + case OP_PARAM: + case COND_PARAM: case STR_PARAM: add_next_index_stringl( ¶ms, @@ -119,14 +123,41 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * add_next_index_long(¶ms, next->num); break; + case METHOD_PARAM: + spprintf(&buffered, 0, "%s::%s" + TSRMLS_CC, next->method.class, next->method.name); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_METHOD_PARAM: + spprintf(&buffered, 0, "%s::%s#%ld" + TSRMLS_CC, next->method.class, next->method.name, next->num); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_FUNCTION_PARAM: + spprintf(&buffered, 0, "%s#%ld" + TSRMLS_CC, next->str, next->num); + add_next_index_string(¶ms, buffered, 0); + break; + + case FILE_PARAM: + spprintf(&buffered, 0, "%s:%ld" + TSRMLS_CC, next->file.name, next->file.line); + add_next_index_string(¶ms, buffered, 0); + break; + + case NUMERIC_FILE_PARAM: + spprintf(&buffered, 0, "%s:#%ld" + TSRMLS_CC, next->file.name, next->file.line); + add_next_index_string(¶ms, buffered, 0); + break; + default: { /* not yet */ } } - phpdbg_debug( - "created param[%d] from argv[%d]: %s", - param, param+1, next->str); next = next->next; } diff --git a/test.php b/test.php index 5fdbcbe1a45..3618ce2391c 100644 --- a/test.php +++ b/test.php @@ -13,6 +13,10 @@ class phpdbg { } } +function mine() { + var_dump(func_get_args()); +} + function test($x, $y = 0) { $var = $x + 1; $var += 2; From 623888adc026bd9f9492a676881622617c5e4d1f Mon Sep 17 00:00:00 2001 From: krakjoe Date: Thu, 27 Feb 2014 19:10:59 +0000 Subject: [PATCH 080/137] use php streams to handle line endings better for #81 --- dev/phpdbg_lexer.l | 33 ++++++---------- phpdbg.c | 1 + phpdbg_lexer.c | 50 ++++++++++++++---------- phpdbg_lexer.h | 2 +- phpdbg_list.c | 95 ++++++++++++---------------------------------- 5 files changed, 68 insertions(+), 113 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index d371e59c599..a50360d2499 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -12,12 +12,18 @@ #include #include -static inline int phpdbg_needs_params(phpdbg_param_t *param TSRMLS_DC) { - return 0; +static inline void phpdbg_append_string(phpdbg_param_t *param, const char *string, size_t length TSRMLS_DC) { + if (!param->str) { + param->str = malloc(length+1); + } else param->str = realloc(param->str, param->len + (length+1)); + + memcpy(¶m->str[param->len], string, length); + param->len += length; + param->str[param->len] = 0; } %} -%s RAW +%s RAW %option outfile="sapi/phpdbg/phpdbg_lexer.c" header-file="sapi/phpdbg/phpdbg_lexer.h" %option warn nodefault @@ -44,24 +50,7 @@ ADDR 0x[a-fA-F0-9]+ OPCODE ?i:ZEND_([A-Za-z])+ INPUT [^\n]+ %% -[a-zA-Z]+ { - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - if (phpdbg_needs_params(yylval TSRMLS_CC)) { - BEGIN(PARAMS); - } - return T_ID; -} - -[0-9]+ { - phpdbg_init_param(yylval, NUMERIC_PARAM); - yylval->num = atoi(yytext); - return T_ID; -} - - -{ +{ [#]{1} { return T_POUND; } [:]{2} { return T_DCOLON; } [:]{1} { return T_COLON; } @@ -113,6 +102,7 @@ INPUT [^\n]+ return T_ID; } } + {INPUT} { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -120,5 +110,6 @@ INPUT [^\n]+ BEGIN(INITIAL); return T_INPUT; } + {WS} { /* ignore whitespace */ } %% diff --git a/phpdbg.c b/phpdbg.c index b08b09ff989..d830092797e 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -144,6 +144,7 @@ static void php_phpdbg_destroy_registered(void *data) /* {{{ */ function TSRMLS_CC); } /* }}} */ + static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ { zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0); diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 841f9b24441..880403775ed 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -513,8 +513,18 @@ static yyconst flex_int16_t yy_chk[231] = #include #include +static inline void phpdbg_append_string(phpdbg_param_t *param, const char *string, size_t length TSRMLS_DC) { + if (!param->str) { + param->str = malloc(length+1); + } else param->str = realloc(param->str, param->len + (length+1)); + + memcpy(¶m->str[param->len], string, length); + param->len += length; + param->str[param->len] = 0; +} + #define YY_NO_UNISTD_H 1 -#line 518 "sapi/phpdbg/phpdbg_lexer.c" +#line 528 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -752,9 +762,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 42 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 52 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 758 "sapi/phpdbg/phpdbg_lexer.c" +#line 768 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -837,22 +847,22 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 45 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_POUND; } YY_BREAK case 2: YY_RULE_SETUP -#line 46 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_DCOLON; } YY_BREAK case 3: YY_RULE_SETUP -#line 47 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 56 "sapi/phpdbg/dev/phpdbg_lexer.l" { return T_COLON; } YY_BREAK case 4: YY_RULE_SETUP -#line 48 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 57 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -861,7 +871,7 @@ YY_RULE_SETUP YY_BREAK case 5: YY_RULE_SETUP -#line 53 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 62 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -870,7 +880,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 58 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 67 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -879,7 +889,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 72 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -888,7 +898,7 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 77 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; @@ -897,7 +907,7 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 82 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -906,7 +916,7 @@ YY_RULE_SETUP YY_BREAK case 10: YY_RULE_SETUP -#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 87 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); @@ -915,7 +925,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 83 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 92 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -925,7 +935,7 @@ YY_RULE_SETUP YY_BREAK case 12: YY_RULE_SETUP -#line 89 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 98 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -936,7 +946,7 @@ YY_RULE_SETUP case 13: YY_RULE_SETUP -#line 96 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -948,15 +958,15 @@ YY_RULE_SETUP case 14: /* rule 14 can match eol */ YY_RULE_SETUP -#line 103 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 114 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK case 15: YY_RULE_SETUP -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 960 "sapi/phpdbg/phpdbg_lexer.c" +#line 970 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -2122,7 +2132,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 88aef381a17..c143d007fde 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -339,7 +339,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 346 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_list.c b/phpdbg_list.c index 37c0851f77c..96c47287071 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -30,6 +30,7 @@ #include "phpdbg_list.h" #include "phpdbg_utils.h" #include "phpdbg_prompt.h" +#include "php_streams.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -53,6 +54,7 @@ PHPDBG_LIST(lines) /* {{{ */ switch (param->type) { case NUMERIC_PARAM: + printf("list lines: %d\n", param->num); phpdbg_list_file(phpdbg_current_file(TSRMLS_C), (param->num < 0 ? 1 - param->num : param->num), (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), @@ -125,97 +127,48 @@ PHPDBG_LIST(class) /* {{{ */ void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */ { - unsigned char *mem, *pos, *last_pos, *end_pos; struct stat st; -#ifndef _WIN32 - int fd; -#else - HANDLE fd, map; -#endif - int all_content = (count == 0); - int line = 0, displayed = 0; - + char *opened = NULL, + *mem = NULL; + char buffer[8096] = {0,}; + size_t buflen = 0L; + long line = 0; + + php_stream *stream = NULL; + if (VCWD_STAT(filename, &st) == FAILURE) { phpdbg_error("Failed to stat file %s", filename); return; } - -#ifndef _WIN32 - if ((fd = VCWD_OPEN(filename, O_RDONLY)) == FAILURE) { + + stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened); + + if (!stream) { phpdbg_error("Failed to open file %s to list", filename); return; } - - pos = last_pos = mem = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - end_pos = mem + st.st_size; -#else - - fd = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (fd == INVALID_HANDLE_VALUE) { - phpdbg_error("Failed to open file!"); - return; - } - - map = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); - if (map == NULL) { - phpdbg_error("Failed to map file!"); - CloseHandle(fd); - return; - } - - pos = last_pos = mem = (char*) MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0); - if (mem == NULL) { - phpdbg_error("Failed to map file in memory"); - CloseHandle(map); - CloseHandle(fd); - return; - } - end_pos = mem + st.st_size; -#endif - while (1) { - if (pos == end_pos) { - break; - } - - pos = memchr(last_pos, '\n', end_pos - last_pos); - - if (!pos) { - /* No more line breaks */ - pos = end_pos; - } - + + while ((buflen = php_stream_gets(stream, buffer, sizeof(buffer))) > 0L) { ++line; - + if (!offset || offset <= line) { /* Without offset, or offset reached */ if (!highlight) { - phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write("%05u: %s", line, buffer); } else { if (highlight != line) { - phpdbg_writeln(" %05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write(" %05u: %s", line, buffer); } else { - phpdbg_writeln(">%05u: %.*s", line, (int)(pos - last_pos), last_pos); + phpdbg_write(">%05u: %s", line, buffer); } } - ++displayed; } - - last_pos = pos + 1; - - if (!all_content && displayed == count) { - /* Reached max line to display */ + + if ((count + (offset-1)) == line) break; - } } - -#ifndef _WIN32 - munmap(mem, st.st_size); - close(fd); -#else - UnmapViewOfFile(mem); - CloseHandle(map); - CloseHandle(fd); -#endif + + php_stream_close(stream); } /* }}} */ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */ From a2d7e336e6f40556fc2e508cf2500907aaf5760b Mon Sep 17 00:00:00 2001 From: krakjoe Date: Fri, 28 Feb 2014 07:41:34 +0000 Subject: [PATCH 081/137] parse stream locations properly, bp.c still needs work for #82 --- dev/phpdbg_lexer.l | 12 +- dev/phpdbg_parser.y | 28 ++++- phpdbg_bp.c | 18 ++- phpdbg_lexer.c | 264 ++++++++++++++++++++++++-------------------- phpdbg_lexer.h | 2 +- phpdbg_parser.c | 209 +++++++++++++++++++++-------------- phpdbg_parser.h | 15 +-- 7 files changed, 323 insertions(+), 225 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index a50360d2499..fc63930e7e4 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -51,9 +51,15 @@ OPCODE ?i:ZEND_([A-Za-z])+ INPUT [^\n]+ %% { - [#]{1} { return T_POUND; } - [:]{2} { return T_DCOLON; } - [:]{1} { return T_COLON; } + {ID}[:]{1}[//]{2} { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_PROTO; + } + [#]{1} { return T_POUND; } + [:]{2} { return T_DCOLON; } + [:]{1} { return T_COLON; } {T_EVAL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 37ecb9e8600..9d31a5d3e7a 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -61,7 +61,7 @@ typedef void* yyscan_t; %token T_COLON ": (colon)" %token T_DCOLON ":: (double colon)" %token T_POUND "# (pound sign)" - +%token T_PROTO "protocol (file://)" %token T_DIGITS "digits (numbers)" %token T_LITERAL "literal (string)" %token T_ADDR "address" @@ -84,14 +84,36 @@ parameters parameter : T_ID T_COLON T_DIGITS { $$.type = FILE_PARAM; - $$.file.name = $1.str; + $$.file.name = $2.str; $$.file.line = $3.num; } - | T_ID T_COLON T_POUND T_DIGITS { + | T_ID T_COLON T_POUND T_DIGITS { $$.type = NUMERIC_FILE_PARAM; $$.file.name = $1.str; $$.file.line = $4.num; } + | T_PROTO T_ID T_COLON T_DIGITS { + $$.type = FILE_PARAM; + $$.file.name = malloc($1.len + + $2.len + 1); + if ($$.file.name) { + memcpy(&$$.file.name[0], $1.str, $1.len); + memcpy(&$$.file.name[$1.len], $2.str, $2.len); + $$.file.name[$1.len + $2.len] = '\0'; + } + $$.file.line = $4.num; + } + | T_PROTO T_ID T_COLON T_POUND T_DIGITS { + $$.type = NUMERIC_FILE_PARAM; + $$.file.name = malloc($1.len + + $2.len + 1); + if ($$.file.name) { + memcpy(&$$.file.name[0], $1.str, $1.len); + memcpy(&$$.file.name[$1.len], $2.str, $2.len); + $$.file.name[$1.len + $2.len] = '\0'; + } + $$.file.line = $5.num; + } | T_ID T_DCOLON T_ID { $$.type = METHOD_PARAM; $$.method.class = $1.str; diff --git a/phpdbg_bp.c b/phpdbg_bp.c index e3e9b8f2451..111d5ca1c90 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -221,14 +221,20 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */ { - struct stat sb; - - if (VCWD_STAT(path, &sb) != FAILURE) { - if (sb.st_mode & (S_IFREG|S_IFLNK)) { + php_stream_statbuf ssb; + char realpath[MAXPATHLEN]; + + if (php_stream_stat_path(path, &ssb) != FAILURE) { + if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) { HashTable *broken; phpdbg_breakfile_t new_break; - size_t path_len = strlen(path); - + size_t path_len = 0L; + + if (VCWD_REALPATH(path, realpath)) { + path = realpath; + } + path_len = strlen(path); + if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, (void**)&broken) == FAILURE) { HashTable breaks; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 880403775ed..7e29e1d661f 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -350,8 +350,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 +#define YY_NUM_RULES 16 +#define YY_END_OF_BUFFER 17 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -359,15 +359,15 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[67] = +static yyconst flex_int16_t yy_accept[70] = { 0, - 0, 0, 0, 0, 16, 12, 14, 1, 9, 9, - 3, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 13, 13, 12, 14, 9, 12, 2, 12, 12, - 4, 12, 6, 8, 12, 7, 5, 12, 12, 12, - 13, 13, 10, 12, 12, 12, 8, 12, 7, 12, - 12, 12, 12, 7, 12, 12, 12, 8, 12, 12, - 12, 11, 12, 7, 8, 0 + 0, 0, 0, 0, 17, 13, 15, 2, 10, 10, + 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 14, 14, 13, 0, 15, 10, 13, 3, 13, + 13, 5, 13, 7, 9, 13, 8, 6, 13, 13, + 13, 14, 14, 0, 11, 13, 13, 13, 9, 13, + 8, 13, 1, 13, 13, 13, 8, 13, 13, 13, + 9, 13, 13, 13, 12, 13, 8, 9, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -376,16 +376,16 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 5, 1, 6, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 8, 1, 1, - 1, 1, 1, 1, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 15, 15, 18, 15, 19, 20, 15, - 15, 21, 22, 23, 24, 25, 15, 15, 26, 27, - 1, 1, 1, 1, 28, 1, 29, 30, 11, 31, + 1, 1, 1, 1, 1, 5, 6, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, + 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 16, 16, 19, 16, 20, 21, 16, + 16, 22, 23, 24, 25, 26, 16, 16, 27, 28, + 1, 1, 1, 1, 29, 1, 30, 31, 12, 32, - 32, 33, 15, 34, 35, 15, 15, 36, 15, 37, - 38, 15, 15, 39, 40, 41, 42, 43, 15, 44, - 45, 46, 1, 1, 1, 1, 1, 1, 1, 1, + 33, 34, 16, 35, 36, 16, 16, 37, 16, 38, + 39, 16, 16, 40, 41, 42, 43, 44, 16, 45, + 46, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -402,93 +402,107 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[47] = +static yyconst flex_int32_t yy_meta[48] = { 0, - 1, 2, 3, 2, 1, 1, 1, 2, 1, 1, + 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[71] = +static yyconst flex_int16_t yy_base[74] = { 0, - 0, 0, 45, 47, 148, 0, 49, 184, 48, 51, - 138, 42, 41, 52, 49, 42, 50, 51, 47, 57, - 58, 0, 70, 0, 72, 86, 90, 184, 54, 79, - 0, 80, 0, 0, 91, 0, 0, 83, 87, 91, - 0, 109, 0, 97, 103, 92, 0, 102, 0, 105, - 108, 111, 117, 0, 117, 117, 118, 0, 136, 126, - 128, 150, 132, 0, 0, 184, 178, 78, 181, 64 + 0, 0, 46, 48, 213, 198, 50, 238, 49, 54, + 197, 46, 51, 56, 58, 59, 63, 67, 65, 61, + 76, 0, 101, 187, 186, 104, 103, 106, 238, 118, + 113, 182, 115, 178, 176, 116, 171, 148, 117, 121, + 126, 0, 126, 142, 0, 123, 136, 140, 91, 142, + 87, 145, 238, 157, 146, 160, 84, 161, 152, 164, + 82, 193, 170, 163, 203, 173, 79, 72, 238, 232, + 78, 235, 68 } ; -static yyconst flex_int16_t yy_def[71] = +static yyconst flex_int16_t yy_def[74] = { 0, - 66, 1, 67, 67, 66, 68, 66, 66, 68, 68, - 66, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 68, 69, 69, 68, 66, 68, 68, 66, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, - 69, 69, 27, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, 70, 68, - 68, 70, 68, 68, 68, 0, 66, 66, 66, 66 + 69, 1, 70, 70, 69, 71, 69, 69, 71, 71, + 69, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 72, 72, 71, 69, 69, 71, 71, 69, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 72, 72, 69, 28, 71, 71, 71, 71, 71, + 71, 71, 69, 71, 71, 71, 71, 71, 71, 71, + 71, 73, 71, 71, 73, 71, 71, 71, 0, 69, + 69, 69, 69 } ; -static yyconst flex_int16_t yy_nxt[231] = +static yyconst flex_int16_t yy_nxt[286] = { 0, - 6, 7, 7, 8, 9, 10, 9, 11, 6, 6, - 6, 12, 13, 14, 6, 6, 15, 6, 16, 17, - 6, 18, 19, 6, 6, 20, 21, 6, 6, 6, - 12, 13, 14, 6, 15, 6, 16, 17, 6, 18, - 19, 6, 6, 6, 20, 21, 23, 7, 23, 7, - 25, 25, 26, 26, 26, 26, 26, 26, 29, 30, - 32, 34, 33, 35, 62, 31, 37, 38, 36, 39, - 40, 42, 25, 25, 25, 44, 29, 30, 24, 34, - 32, 33, 35, 31, 37, 38, 36, 45, 39, 40, - 26, 26, 26, 44, 27, 43, 43, 46, 43, 43, + 6, 7, 7, 8, 9, 6, 10, 9, 11, 6, + 6, 6, 12, 13, 14, 6, 6, 15, 6, 16, + 17, 6, 18, 19, 6, 6, 20, 21, 6, 6, + 6, 12, 13, 14, 6, 15, 6, 16, 17, 6, + 18, 19, 6, 6, 6, 20, 21, 23, 7, 23, + 7, 26, 26, 27, 25, 27, 27, 25, 27, 25, + 27, 27, 25, 30, 25, 33, 25, 25, 65, 25, + 31, 25, 34, 25, 40, 25, 32, 36, 24, 35, + 25, 30, 37, 38, 25, 33, 39, 25, 31, 41, + 25, 34, 25, 40, 32, 25, 36, 35, 28, 25, - 43, 43, 43, 43, 47, 51, 48, 45, 49, 50, - 42, 25, 52, 53, 54, 46, 55, 56, 43, 43, - 43, 43, 43, 47, 48, 51, 49, 50, 57, 58, - 61, 53, 52, 54, 60, 55, 24, 56, 63, 64, - 24, 24, 24, 65, 59, 28, 57, 66, 58, 61, - 24, 66, 60, 66, 24, 24, 24, 63, 64, 66, - 66, 66, 65, 24, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 24, 22, 22, - 22, 41, 41, 5, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 37, 38, 43, 26, 39, 26, 26, 27, 41, 27, + 27, 25, 45, 45, 25, 45, 45, 45, 45, 45, + 45, 25, 47, 25, 25, 25, 25, 43, 26, 25, + 49, 25, 54, 48, 25, 45, 45, 45, 45, 45, + 46, 50, 47, 51, 25, 52, 55, 53, 25, 49, + 25, 48, 54, 25, 25, 57, 25, 58, 46, 50, + 25, 51, 56, 52, 60, 25, 55, 59, 25, 25, + 63, 25, 25, 61, 57, 67, 58, 64, 25, 25, + 56, 25, 60, 66, 25, 68, 25, 59, 63, 62, + 25, 44, 61, 24, 67, 25, 64, 24, 24, 24, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66 + 24, 25, 66, 24, 68, 29, 25, 24, 24, 24, + 24, 25, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 24, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 24, 22, 22, 22, 42, 42, 5, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69 } ; -static yyconst flex_int16_t yy_chk[231] = +static yyconst flex_int16_t yy_chk[286] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, - 7, 7, 9, 9, 9, 10, 10, 10, 12, 13, - 14, 16, 15, 17, 70, 13, 18, 19, 17, 20, - 21, 23, 23, 25, 25, 29, 12, 13, 68, 16, - 14, 15, 17, 13, 18, 19, 17, 30, 20, 21, - 26, 26, 26, 29, 10, 27, 27, 32, 27, 27, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, + 4, 7, 7, 9, 12, 9, 9, 9, 10, 13, + 10, 10, 10, 12, 14, 14, 15, 16, 73, 20, + 13, 17, 15, 19, 20, 18, 13, 17, 71, 16, + 68, 12, 17, 18, 21, 14, 19, 67, 13, 21, + 61, 15, 57, 20, 13, 51, 17, 16, 10, 49, - 27, 27, 27, 27, 35, 44, 38, 30, 39, 40, - 42, 42, 45, 46, 48, 32, 50, 51, 27, 27, - 27, 27, 27, 35, 38, 44, 39, 40, 52, 53, - 57, 46, 45, 48, 56, 50, 59, 51, 60, 61, - 59, 59, 59, 63, 55, 11, 52, 5, 53, 57, - 62, 0, 56, 0, 62, 62, 62, 60, 61, 0, - 0, 0, 63, 59, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 62, 67, 67, - 67, 69, 69, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 17, 18, 23, 23, 19, 26, 26, 27, 21, 27, + 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 31, 31, 33, 36, 39, 30, 43, 43, 40, + 36, 46, 46, 33, 41, 28, 28, 28, 28, 28, + 30, 39, 31, 40, 47, 41, 47, 44, 48, 36, + 50, 33, 46, 52, 55, 50, 38, 52, 30, 39, + 59, 40, 48, 41, 55, 54, 47, 54, 56, 58, + 59, 64, 60, 56, 50, 64, 52, 60, 63, 37, + 48, 66, 55, 63, 35, 66, 34, 54, 59, 58, + 32, 25, 56, 62, 64, 24, 60, 62, 62, 62, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66 + 62, 62, 63, 65, 66, 11, 6, 65, 65, 65, + 65, 65, 5, 0, 0, 0, 0, 0, 0, 0, + 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 65, 70, 70, 70, 72, 72, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69 } ; /* The intent behind this definition is that it'll catch @@ -524,7 +538,7 @@ static inline void phpdbg_append_string(phpdbg_param_t *param, const char *strin } #define YY_NO_UNISTD_H 1 -#line 528 "sapi/phpdbg/phpdbg_lexer.c" +#line 542 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -764,7 +778,7 @@ YY_DECL #line 52 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 768 "sapi/phpdbg/phpdbg_lexer.c" +#line 782 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -819,13 +833,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 67 ) + if ( yy_current_state >= 70 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 66 ); + while ( yy_current_state != 69 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -848,84 +862,94 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP #line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ return T_POUND; } +{ + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_PROTO; + } YY_BREAK case 2: YY_RULE_SETUP -#line 55 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ return T_DCOLON; } +#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_POUND; } YY_BREAK case 3: YY_RULE_SETUP -#line 56 "sapi/phpdbg/dev/phpdbg_lexer.l" -{ return T_COLON; } +#line 61 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_DCOLON; } YY_BREAK case 4: YY_RULE_SETUP -#line 57 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 62 "sapi/phpdbg/dev/phpdbg_lexer.l" +{ return T_COLON; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_EVAL; } YY_BREAK -case 5: +case 6: YY_RULE_SETUP -#line 62 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } YY_BREAK -case 6: +case 7: YY_RULE_SETUP -#line 67 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } YY_BREAK -case 7: +case 8: YY_RULE_SETUP -#line 72 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } YY_BREAK -case 8: +case 9: YY_RULE_SETUP -#line 77 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 83 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 82 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 88 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 87 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 93 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, NULL, 10); return T_ADDR; } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 92 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 98 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -933,9 +957,9 @@ YY_RULE_SETUP return T_OPCODE; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 98 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -944,9 +968,9 @@ YY_RULE_SETUP } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 106 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -955,18 +979,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 14: -/* rule 14 can match eol */ +case 15: +/* rule 15 can match eol */ YY_RULE_SETUP -#line 114 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 15: +case 16: YY_RULE_SETUP -#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 970 "sapi/phpdbg/phpdbg_lexer.c" +#line 994 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1262,7 +1286,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 67 ) + if ( yy_current_state >= 70 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1291,11 +1315,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 67 ) + if ( yy_current_state >= 70 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 66); + yy_is_jam = (yy_current_state == 69); (void)yyg; return yy_is_jam ? 0 : yy_current_state; @@ -2132,7 +2156,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index c143d007fde..14dc12ef5a9 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -339,7 +339,7 @@ extern int yylex \ #undef YY_DECL #endif -#line 115 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" #line 346 "sapi/phpdbg/phpdbg_lexer.h" diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 1f6a1515876..6ea96d84d51 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -160,13 +160,14 @@ typedef void* yyscan_t; T_COLON = 264, T_DCOLON = 265, T_POUND = 266, - T_DIGITS = 267, - T_LITERAL = 268, - T_ADDR = 269, - T_OPCODE = 270, - T_ID = 271, - T_INPUT = 272, - T_UNEXPECTED = 273 + T_PROTO = 267, + T_DIGITS = 268, + T_LITERAL = 269, + T_ADDR = 270, + T_OPCODE = 271, + T_ID = 272, + T_INPUT = 273, + T_UNEXPECTED = 274 }; #endif @@ -198,7 +199,7 @@ int yyparse (); /* Copy the second part of user declarations. */ /* Line 390 of yacc.c */ -#line 202 "sapi/phpdbg/phpdbg_parser.c" +#line 203 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -416,22 +417,22 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 20 +#define YYFINAL 22 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 25 +#define YYLAST 31 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 19 +#define YYNTOKENS 20 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 20 +#define YYNRULES 22 /* YYNRULES -- Number of states. */ -#define YYNSTATES 29 +#define YYNSTATES 35 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 273 +#define YYMAXUTOK 274 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -466,7 +467,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18 + 15, 16, 17, 18, 19 }; #if YYDEBUG @@ -474,28 +475,29 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 6, 8, 11, 15, 20, 24, - 30, 34, 37, 40, 43, 45, 47, 49, 51, 53, - 55 + 0, 0, 3, 5, 6, 8, 11, 15, 20, 25, + 31, 35, 41, 45, 48, 51, 54, 56, 58, 60, + 62, 64, 66 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 20, 0, -1, 21, -1, -1, 22, -1, 21, 22, - -1, 16, 9, 12, -1, 16, 9, 11, 12, -1, - 16, 10, 16, -1, 16, 10, 16, 11, 12, -1, - 16, 11, 12, -1, 5, 17, -1, 3, 17, -1, - 4, 17, -1, 15, -1, 14, -1, 13, -1, 6, - -1, 7, -1, 12, -1, 16, -1 + 21, 0, -1, 22, -1, -1, 23, -1, 22, 23, + -1, 17, 9, 13, -1, 17, 9, 11, 13, -1, + 12, 17, 9, 13, -1, 12, 17, 9, 11, 13, + -1, 17, 10, 17, -1, 17, 10, 17, 11, 13, + -1, 17, 11, 13, -1, 5, 18, -1, 3, 18, + -1, 4, 18, -1, 16, -1, 15, -1, 14, -1, + 6, -1, 7, -1, 13, -1, 17, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 75, 75, 76, 80, 81, 85, 90, 95, 100, - 106, 112, 117, 122, 127, 128, 129, 130, 131, 132, - 133 + 0, 75, 75, 76, 80, 81, 85, 90, 95, 106, + 117, 122, 128, 134, 139, 144, 149, 150, 151, 152, + 153, 154, 155 }; #endif @@ -508,9 +510,9 @@ static const char *const yytname[] = "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", "\"falsy (false, off, no or disabled)\"", "\"string (some input, perhaps)\"", "\": (colon)\"", - "\":: (double colon)\"", "\"# (pound sign)\"", "\"digits (numbers)\"", - "\"literal (string)\"", "\"address\"", "\"opcode\"", - "\"identifier (command or function name)\"", + "\":: (double colon)\"", "\"# (pound sign)\"", "\"protocol (file://)\"", + "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", + "\"opcode\"", "\"identifier (command or function name)\"", "\"input (input string or data)\"", "\"input\"", "$accept", "input", "parameters", "parameter", YY_NULL }; @@ -522,24 +524,24 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273 + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 19, 20, 20, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22 + 0, 20, 21, 21, 22, 22, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 1, 2, 3, 4, 3, 5, - 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, - 1 + 0, 2, 1, 0, 1, 2, 3, 4, 4, 5, + 3, 5, 3, 2, 2, 2, 1, 1, 1, 1, + 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -547,31 +549,33 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 0, 17, 18, 19, 16, 15, 14, - 20, 0, 2, 4, 12, 13, 11, 0, 0, 0, - 1, 5, 0, 6, 8, 10, 7, 0, 9 + 3, 0, 0, 0, 19, 20, 0, 21, 18, 17, + 16, 22, 0, 2, 4, 14, 15, 13, 0, 0, + 0, 0, 1, 5, 0, 0, 6, 10, 12, 0, + 8, 7, 0, 9, 11 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 11, 12, 13 + -1, 12, 13, 14 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -10 +#define YYPACT_NINF -11 static const yytype_int8 yypact[] = { - -3, -9, -1, 0, -10, -10, -10, -10, -10, -10, - -4, 18, -3, -10, -10, -10, -10, 3, 4, 7, - -10, -10, 9, -10, 11, -10, -10, 12, -10 + -3, -10, 1, 2, -11, -11, 6, -11, -11, -11, + -11, -4, 21, -3, -11, -11, -11, -11, 13, 4, + 7, 12, -11, -11, 5, 14, -11, 15, -11, 16, + -11, -11, 17, -11, -11 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -10, -10, -10, 13 + -11, -11, -11, 18 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -580,22 +584,24 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 1, 2, 3, 4, 5, 17, 18, 19, 14, 6, - 7, 8, 9, 10, 22, 23, 15, 16, 20, 25, - 24, 26, 27, 0, 28, 21 + 1, 2, 3, 4, 5, 19, 20, 21, 15, 6, + 7, 8, 9, 10, 11, 25, 29, 26, 30, 16, + 17, 22, 24, 18, 27, 28, 32, 31, 0, 33, + 34, 23 }; #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-10))) + (!!((Yystate) == (-11))) #define yytable_value_is_error(Yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 3, 4, 5, 6, 7, 9, 10, 11, 17, 12, - 13, 14, 15, 16, 11, 12, 17, 17, 0, 12, - 16, 12, 11, -1, 12, 12 + 3, 4, 5, 6, 7, 9, 10, 11, 18, 12, + 13, 14, 15, 16, 17, 11, 11, 13, 13, 18, + 18, 0, 9, 17, 17, 13, 11, 13, -1, 13, + 13, 13 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -603,8 +609,9 @@ static const yytype_int8 yycheck[] = static const yytype_uint8 yystos[] = { 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, - 16, 20, 21, 22, 17, 17, 17, 9, 10, 11, - 0, 22, 11, 12, 16, 12, 12, 11, 12 + 16, 17, 21, 22, 23, 18, 18, 18, 17, 9, + 10, 11, 0, 23, 9, 11, 13, 17, 13, 11, + 13, 13, 11, 13, 13 }; #define yyerrok (yyerrstatus = 0) @@ -1447,7 +1454,7 @@ yyreduce: #line 85 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = FILE_PARAM; - (yyval).file.name = (yyvsp[(1) - (3)]).str; + (yyval).file.name = (yyvsp[(2) - (3)]).str; (yyval).file.line = (yyvsp[(3) - (3)]).num; } break; @@ -1465,6 +1472,38 @@ yyreduce: case 8: /* Line 1792 of yacc.c */ #line 95 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = FILE_PARAM; + (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + + (yyvsp[(2) - (4)]).len + 1); + if ((yyval).file.name) { + memcpy(&(yyval).file.name[0], (yyvsp[(1) - (4)]).str, (yyvsp[(1) - (4)]).len); + memcpy(&(yyval).file.name[(yyvsp[(1) - (4)]).len], (yyvsp[(2) - (4)]).str, (yyvsp[(2) - (4)]).len); + (yyval).file.name[(yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len] = '\0'; + } + (yyval).file.line = (yyvsp[(4) - (4)]).num; + } + break; + + case 9: +/* Line 1792 of yacc.c */ +#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" + { + (yyval).type = NUMERIC_FILE_PARAM; + (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + + (yyvsp[(2) - (5)]).len + 1); + if ((yyval).file.name) { + memcpy(&(yyval).file.name[0], (yyvsp[(1) - (5)]).str, (yyvsp[(1) - (5)]).len); + memcpy(&(yyval).file.name[(yyvsp[(1) - (5)]).len], (yyvsp[(2) - (5)]).str, (yyvsp[(2) - (5)]).len); + (yyval).file.name[(yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len] = '\0'; + } + (yyval).file.line = (yyvsp[(5) - (5)]).num; + } + break; + + case 10: +/* Line 1792 of yacc.c */ +#line 117 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (3)]).str; @@ -1472,9 +1511,9 @@ yyreduce: } break; - case 9: + case 11: /* Line 1792 of yacc.c */ -#line 100 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; (yyval).method.class = (yyvsp[(1) - (5)]).str; @@ -1483,9 +1522,9 @@ yyreduce: } break; - case 10: + case 12: /* Line 1792 of yacc.c */ -#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; (yyval).str = (yyvsp[(1) - (3)]).str; @@ -1494,9 +1533,9 @@ yyreduce: } break; - case 11: + case 13: /* Line 1792 of yacc.c */ -#line 112 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 134 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = COND_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1504,9 +1543,9 @@ yyreduce: } break; - case 12: + case 14: /* Line 1792 of yacc.c */ -#line 117 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 139 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1514,9 +1553,9 @@ yyreduce: } break; - case 13: + case 15: /* Line 1792 of yacc.c */ -#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; (yyval).str = (yyvsp[(2) - (2)]).str; @@ -1524,51 +1563,51 @@ yyreduce: } break; - case 14: -/* Line 1792 of yacc.c */ -#line 127 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 15: -/* Line 1792 of yacc.c */ -#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - case 16: /* Line 1792 of yacc.c */ -#line 129 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 149 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: /* Line 1792 of yacc.c */ -#line 130 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 150 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: /* Line 1792 of yacc.c */ -#line 131 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 151 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: /* Line 1792 of yacc.c */ -#line 132 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 152 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: /* Line 1792 of yacc.c */ -#line 133 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 153 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 21: +/* Line 1792 of yacc.c */ +#line 154 "sapi/phpdbg/dev/phpdbg_parser.y" + { (yyval) = (yyvsp[(1) - (1)]); } + break; + + case 22: +/* Line 1792 of yacc.c */ +#line 155 "sapi/phpdbg/dev/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; /* Line 1792 of yacc.c */ -#line 1572 "sapi/phpdbg/phpdbg_parser.c" +#line 1611 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1800,5 +1839,5 @@ yyreturn: /* Line 2055 of yacc.c */ -#line 136 "sapi/phpdbg/dev/phpdbg_parser.y" +#line 158 "sapi/phpdbg/dev/phpdbg_parser.y" diff --git a/phpdbg_parser.h b/phpdbg_parser.h index a9eea7a56be..3a57a5e54ff 100644 --- a/phpdbg_parser.h +++ b/phpdbg_parser.h @@ -68,13 +68,14 @@ typedef void* yyscan_t; T_COLON = 264, T_DCOLON = 265, T_POUND = 266, - T_DIGITS = 267, - T_LITERAL = 268, - T_ADDR = 269, - T_OPCODE = 270, - T_ID = 271, - T_INPUT = 272, - T_UNEXPECTED = 273 + T_PROTO = 267, + T_DIGITS = 268, + T_LITERAL = 269, + T_ADDR = 270, + T_OPCODE = 271, + T_ID = 272, + T_INPUT = 273, + T_UNEXPECTED = 274 }; #endif From 37ca791a91f3364f6f67c3ed79bb3ce930ad77f1 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 8 Mar 2014 09:52:57 -0500 Subject: [PATCH 082/137] Fixed recursive segfault in segfault handler --- phpdbg_watch.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 18c3f447a65..50d6a90f645 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -398,7 +398,7 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) /* re-enable writing */ mprotect(page, size, PROT_NONE | PROT_READ | PROT_WRITE); - dump = emalloc(MEMDUMP_SIZE(size)); + dump = malloc(MEMDUMP_SIZE(size)); dump->page = page; dump->size = size; @@ -431,7 +431,7 @@ static void phpdbg_watch_mem_dtor(void *llist_data) { void *page = (*(phpdbg_watch_memdump **)llist_data)->page; size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; - efree(*(void **)llist_data); + free(*(void **)llist_data); /* Disble writing again */ mprotect(page, size, PROT_NONE | PROT_READ); @@ -448,7 +448,7 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); #endif - zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 0); + zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1); phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); _zend_hash_init(&PHPDBG_G(watchpoints), 8, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC); } From b033c4fa287e3ca557ff915c21ada8a87f5dbc8b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 10 Mar 2014 09:10:27 -0400 Subject: [PATCH 083/137] Added handling of zval separation (aka watchpoint changes) --- phpdbg_watch.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 50d6a90f645..1eeb08a1a40 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -453,18 +453,27 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { _zend_hash_init(&PHPDBG_G(watchpoints), 8, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC); } -static int phpdbg_print_changed_zval(void *llist_data) { - TSRMLS_FETCH(); - - phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; +static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { /* fetch all changes between dump->page and dump->page + dump->size */ phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); phpdbg_btree_result *result, *htresult; int elementDiff; + void *curTest; while ((result = phpdbg_btree_next(&pos))) { phpdbg_watchpoint_t *watch = result->ptr, *htwatch; void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + + /* Test if the zval was separated and if necessary move the watchpoint */ + if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len, &curTest) == SUCCESS) { + if (curTest != watch->addr.ptr) { + phpdbg_deactivate_watchpoint(watch); + watch->addr.ptr = curTest; + phpdbg_activate_watchpoint(watch); + } + } + + /* Show to the user what changed and delete watchpoint upon removal */ if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { PHPDBG_G(watchpoint_hit) = 1; @@ -522,17 +531,25 @@ remove_ht_watch: } } } - - return 1; } int phpdbg_print_changed_zvals(TSRMLS_D) { + zend_llist_position pos; + phpdbg_watch_memdump **dump; + if (zend_llist_count(&PHPDBG_G(watchlist_mem)) == 0) { return FAILURE; } PHPDBG_G(watchpoint_hit) = 0; - zend_llist_apply_with_del(&PHPDBG_G(watchlist_mem), phpdbg_print_changed_zval); + + dump = (phpdbg_watch_memdump **)zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos); + + do { + phpdbg_print_changed_zval(*dump TSRMLS_CC); + } while ((dump = (phpdbg_watch_memdump **)zend_llist_get_prev_ex(&PHPDBG_G(watchlist_mem), &pos))); + + zend_llist_clean(&PHPDBG_G(watchlist_mem)); return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; } From 008842c7fab0c6ed68d65eb2c1898db890223f35 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 11 Mar 2014 06:14:32 -0400 Subject: [PATCH 084/137] Added COW handling and fixed various bugs --- phpdbg_watch.c | 77 ++++++++++++++++++++++++++++++++++---------------- phpdbg_watch.h | 4 +++ test.php | 9 ++++++ 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 1eeb08a1a40..85451c88cbf 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -33,6 +33,7 @@ long phpdbg_pagesize; typedef struct { void *page; size_t size; + char reenable_writing; /* data must be last element */ void *data; } phpdbg_watch_memdump; @@ -66,10 +67,6 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) { return watch; } -static void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { - phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); -} - static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) { int m; @@ -90,6 +87,14 @@ static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRML phpdbg_change_watchpoint_access(watch, PROT_READ | PROT_WRITE TSRMLS_CC); } +static inline void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch); +} + +static inline void phpdbg_remove_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); +} + void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { watch->addr.ptr = addr; watch->size = size; @@ -180,6 +185,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ new_watch->str = NULL; new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + new_watch->flags = PHPDBG_WATCH_RECURSIVE; phpdbg_create_zval_watchpoint(*zv, new_watch); phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); @@ -190,11 +196,12 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); new_watch->parent = watch; - new_watch->parent_container = ht; + new_watch->parent_container = watch->parent_container; new_watch->name_in_parent = watch->name_in_parent; new_watch->name_in_parent_len = watch->name_in_parent_len; new_watch->str = watch->str; new_watch->str_len = watch->str_len; + new_watch->flags = PHPDBG_WATCH_RECURSIVE; phpdbg_create_ht_watchpoint(ht, new_watch); phpdbg_create_watchpoint(new_watch TSRMLS_CC); @@ -396,7 +403,7 @@ int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) size = phpdbg_get_total_page_size(watch->addr.ptr, watch->size); /* re-enable writing */ - mprotect(page, size, PROT_NONE | PROT_READ | PROT_WRITE); + mprotect(page, size, PROT_READ | PROT_WRITE); dump = malloc(MEMDUMP_SIZE(size)); dump->page = page; @@ -419,7 +426,7 @@ static void phpdbg_watch_dtor(void *pDest) { phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest; phpdbg_deactivate_watchpoint(watch TSRMLS_CC); - phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr); + phpdbg_remove_watchpoint(watch TSRMLS_CC); efree(watch->str); efree(watch->name_in_parent); @@ -428,24 +435,25 @@ static void phpdbg_watch_dtor(void *pDest) { } static void phpdbg_watch_mem_dtor(void *llist_data) { - void *page = (*(phpdbg_watch_memdump **)llist_data)->page; - size_t size = (*(phpdbg_watch_memdump **)llist_data)->size; + phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; free(*(void **)llist_data); /* Disble writing again */ - mprotect(page, size, PROT_NONE | PROT_READ); + if (dump->reenable_writing) { + mprotect(dump->page, dump->size, PROT_NONE | PROT_READ); + } } void phpdbg_setup_watchpoints(TSRMLS_D) { -#ifdef _SC_PAGE_SIZE +#if _SC_PAGE_SIZE phpdbg_pagesize = sysconf(_SC_PAGE_SIZE); -#endif -#ifdef _SC_PAGESIZE +#elif _SC_PAGESIZE phpdbg_pagesize = sysconf(_SC_PAGESIZE); -#endif -#ifdef _SC_NUTC_OS_PAGESIZE +#elif _SC_NUTC_OS_PAGESIZE phpdbg_pagesize = sysconf(_SC_NUTC_OS_PAGESIZE); +#else + phpdbg_pagesize = 4096; /* common pagesize */ #endif zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1); @@ -458,18 +466,29 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); phpdbg_btree_result *result, *htresult; int elementDiff; - void *curTest; + void **curTest; + + dump->reenable_writing = 0; while ((result = phpdbg_btree_next(&pos))) { phpdbg_watchpoint_t *watch = result->ptr, *htwatch; void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); + char reenable = 1; /* Test if the zval was separated and if necessary move the watchpoint */ - if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len, &curTest) == SUCCESS) { - if (curTest != watch->addr.ptr) { - phpdbg_deactivate_watchpoint(watch); - watch->addr.ptr = curTest; - phpdbg_activate_watchpoint(watch); + if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len, (void **) &curTest) == SUCCESS) { + if (watch->type == WATCH_ON_HASHTABLE) { + curTest = (void **)&Z_ARRVAL_PP((zval **)curTest); + } + + if (*curTest != watch->addr.ptr) { + phpdbg_deactivate_watchpoint(watch TSRMLS_CC); + phpdbg_remove_watchpoint(watch TSRMLS_CC); + watch->addr.ptr = *curTest; + phpdbg_store_watchpoint(watch TSRMLS_CC); + phpdbg_activate_watchpoint(watch TSRMLS_CC); + + reenable = 0; } } @@ -490,6 +509,8 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + reenable = 0; + if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY) { goto remove_ht_watch; } @@ -517,11 +538,15 @@ remove_ht_watch: elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); if (elementDiff) { - if (elementDiff < 0) { - phpdbg_writeln("%d elements were removed from the array", -elementDiff); + if (elementDiff > 0) { + phpdbg_writeln("%d elements were removed from the array", elementDiff); } else { - phpdbg_writeln("%d elements were added to the array", elementDiff); - /* TODO: add, if recursive watchpoint, the new elements to the elements to watch */ + phpdbg_writeln("%d elements were added to the array", -elementDiff); + + /* add new watchpoints if necessary */ + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_create_recursive_watchpoint(watch TSRMLS_CC); + } } } if (((HashTable *)oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) { @@ -530,6 +555,8 @@ remove_ht_watch: break; } } + + dump->reenable_writing = dump->reenable_writing | reenable; } } diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 8e530875848..37dcde6147f 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -51,6 +51,9 @@ typedef enum { WATCH_ON_PTR } phpdbg_watchtype; + +#define PHPDBG_WATCH_RECURSIVE 1 + typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; struct _phpdbg_watchpoint_t { @@ -67,6 +70,7 @@ struct _phpdbg_watchpoint_t { } addr; size_t size; phpdbg_watchtype type; + char flags; }; void phpdbg_setup_watchpoints(TSRMLS_D); diff --git a/test.php b/test.php index b4b12a6e290..20be79f8872 100644 --- a/test.php +++ b/test.php @@ -57,9 +57,18 @@ $array = [ [5, 6], ]; +$array[] = 7; + array_walk($array, function (&$item) { if (is_array($item)) $item[0] += 2; else $item -= 1; }); + +$obj = (object)["a" => 2, "b" => 5, "c" => 7]; + +$test = $obj->a; + +$obj->a += 2; +$test -= 2; From 7a9e3e422f159175f7a94f43c411ec300009ba23 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 11 Mar 2014 09:11:27 -0400 Subject: [PATCH 085/137] Added support for recursive watchpoints deletion --- phpdbg_btree.c | 4 +++ phpdbg_btree.h | 1 + phpdbg_watch.c | 97 ++++++++++++++++++++++++++++++++++++++++++-------- phpdbg_watch.h | 1 + 4 files changed, 89 insertions(+), 14 deletions(-) diff --git a/phpdbg_btree.c b/phpdbg_btree.c index f3b86dd91fc..f3b6306a2a9 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -28,6 +28,7 @@ void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth) { tree->depth = depth; tree->branch = NULL; + tree->count = 0; } phpdbg_btree_result *phpdbg_btree_find(phpdbg_btree *tree, zend_ulong idx) { @@ -154,6 +155,7 @@ int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr, branch = &(*branch)->branches[(idx >> i) % 2]; *branch = ++memory; } while (i--); + tree->count++; } } else if (!(flags & PHPDBG_BTREE_UPDATE)) { return FAILURE; @@ -186,6 +188,8 @@ check_branch_existence: } } while (i--); + tree->count--; + if (i_last_dual_branch == -1) { efree(tree->branch); tree->branch = NULL; diff --git a/phpdbg_btree.h b/phpdbg_btree.h index 7bb40aefca6..5fb217db35e 100644 --- a/phpdbg_btree.h +++ b/phpdbg_btree.h @@ -35,6 +35,7 @@ union _phpdbg_btree_branch { }; typedef struct { + zend_ulong count; zend_ulong depth; phpdbg_btree_branch *branch; } phpdbg_btree; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 85451c88cbf..f89b3277ad2 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -112,6 +112,8 @@ void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) { } static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { + watch->flags |= PHPDBG_WATCH_SIMPLE; + phpdbg_store_watchpoint(watch TSRMLS_CC); zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); @@ -148,6 +150,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ return FAILURE; } + watch->flags |= PHPDBG_WATCH_RECURSIVE; phpdbg_create_watchpoint(watch TSRMLS_CC); switch (Z_TYPE_P(watch->addr.zv)) { @@ -171,12 +174,13 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ zend_hash_move_forward_ex(ht, &position)) { phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t)); + new_watch->flags = PHPDBG_WATCH_RECURSIVE; new_watch->parent = watch; new_watch->parent_container = ht; zend_hash_get_current_key_zval_ex(ht, &key, &position); if (Z_TYPE(key) == IS_STRING) { - new_watch->name_in_parent = Z_STRVAL(key); + new_watch->name_in_parent = zend_strndup(Z_STRVAL(key), Z_STRLEN(key)); new_watch->name_in_parent_len = Z_STRLEN(key); } else { new_watch->name_in_parent = NULL; @@ -185,7 +189,6 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ new_watch->str = NULL; new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); - new_watch->flags = PHPDBG_WATCH_RECURSIVE; phpdbg_create_zval_watchpoint(*zv, new_watch); phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); @@ -197,10 +200,10 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ new_watch->parent = watch; new_watch->parent_container = watch->parent_container; - new_watch->name_in_parent = watch->name_in_parent; + new_watch->name_in_parent = zend_strndup(watch->name_in_parent, watch->name_in_parent_len); new_watch->name_in_parent_len = watch->name_in_parent_len; - new_watch->str = watch->str; - new_watch->str_len = watch->str_len; + new_watch->str = NULL; + new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", watch->str_len, watch->str); new_watch->flags = PHPDBG_WATCH_RECURSIVE; phpdbg_create_ht_watchpoint(ht, new_watch); @@ -210,10 +213,74 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ return SUCCESS; } -static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { - int ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); +static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) { + if (watch->type == WATCH_ON_HASHTABLE || (watch->type == WATCH_ON_ZVAL && (Z_TYPE_P(watch->addr.zv) == IS_ARRAY || Z_TYPE_P(watch->addr.zv) == IS_OBJECT))) { + HashTable *ht; + phpdbg_btree_result *result; - efree(watch); + if (watch->type == WATCH_ON_HASHTABLE) { + HashPosition position; + zval **zv; + zval key; + char *str; + int str_len; + phpdbg_watchpoint_t **watchpoint; + + ht = watch->addr.ht; + + for (zend_hash_internal_pointer_reset_ex(ht, &position); + zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS; + zend_hash_move_forward_ex(ht, &position)) { + zend_hash_get_current_key_zval_ex(ht, &key, &position); + str = NULL; + if (Z_TYPE(key) == IS_STRING) { + str_len = asprintf(&str, "%.*s%s%.*s%s", watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_STRLEN(key), Z_STRVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + } else { + str_len = asprintf(&str, "%.*s%s%i%s", watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + } + + if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) { + phpdbg_delete_watchpoint_recursive(*watchpoint TSRMLS_CC); + } + } + } else { + switch (Z_TYPE_P(watch->addr.zv)) { + case IS_ARRAY: + ht = Z_ARRVAL_P(watch->addr.zv); + break; + case IS_OBJECT: + ht = Z_OBJPROP_P(watch->addr.zv); + break; + } + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) ht))) { + phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr TSRMLS_CC); + } + } + } + + return zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); +} + +static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { + int ret; + phpdbg_watchpoint_t *watch; + phpdbg_btree_result *result; + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)tmp_watch->addr.ptr)) == NULL) { + return FAILURE; + } + + watch = result->ptr; + + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + ret = phpdbg_delete_watchpoint_recursive(watch TSRMLS_CC); + } else { + ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + + free(tmp_watch->str); + efree(tmp_watch); return ret; } @@ -266,12 +333,13 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par if (i == len || (i == len - 1 && input[len - 1] == ']')) { zval *key = emalloc(sizeof(zval)); phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); + watch->flags = 0; zend_hash_get_current_key_zval_ex(parent, key, &position); convert_to_string(key); - watch->str = emalloc(i + Z_STRLEN_P(key) + 2); + watch->str = malloc(i + Z_STRLEN_P(key) + 2); watch->str_len = sprintf(watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); efree(key); - watch->name_in_parent = estrndup(last_index, index_len); + watch->name_in_parent = zend_strndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; phpdbg_create_zval_watchpoint(*zv, watch); @@ -296,9 +364,10 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par last_index[index_len] = last_chr; if (i == len) { phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t)); - watch->str = estrndup(input, len); + watch->flags = 0; + watch->str = zend_strndup(input, len); watch->str_len = len; - watch->name_in_parent = estrndup(last_index, index_len); + watch->name_in_parent = zend_strndup(last_index, index_len); watch->name_in_parent_len = index_len; watch->parent_container = parent; phpdbg_create_zval_watchpoint(*zv, watch); @@ -428,8 +497,8 @@ static void phpdbg_watch_dtor(void *pDest) { phpdbg_deactivate_watchpoint(watch TSRMLS_CC); phpdbg_remove_watchpoint(watch TSRMLS_CC); - efree(watch->str); - efree(watch->name_in_parent); + free(watch->str); + free(watch->name_in_parent); efree(watch); } diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 37dcde6147f..1aa3ad75b04 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -52,6 +52,7 @@ typedef enum { } phpdbg_watchtype; +#define PHPDBG_WATCH_SIMPLE 0 #define PHPDBG_WATCH_RECURSIVE 1 typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; From 3fcdd6ab0f8537d49019cbd01809c6a40a869f37 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 16 Mar 2014 19:39:02 +0100 Subject: [PATCH 086/137] Added WINDOWS support for watchpoints Actually it mainly works by just a bit macro substitution and function redeclarations. So it leaves the code working on UNIX mostly untouched. I needed to substitute the allocating functions by a Virtual*() functions wrapper to use VirtualProtect() on the memory. --- Makefile.frag | 4 +-- config.w32 | 9 +++--- phpdbg.c | 49 +++++++++++++++--------------- phpdbg.h | 17 +++++++++-- phpdbg_btree.c | 5 ++++ phpdbg_watch.c | 40 ++++++++++++++----------- phpdbg_watch.h | 23 ++++++++++++-- phpdbg_win.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_win.h | 39 ++++++++++++++++++++++++ 9 files changed, 213 insertions(+), 54 deletions(-) create mode 100644 phpdbg_win.c create mode 100644 phpdbg_win.h diff --git a/Makefile.frag b/Makefile.frag index 5be6d5b00f4..4aebfb40f36 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -23,6 +23,4 @@ test-phpdbg: @echo "Running phpdbg tests ..." @$(top_builddir)/sapi/cli/php sapi/phpdbg/tests/run-tests.php --phpdbg sapi/phpdbg/phpdbg -.PHONY: clean-phpdbg test-phpdbg - - +.PHONY: clean-phpdbg test-phpdbg \ No newline at end of file diff --git a/config.w32 b/config.w32 index 5813e7f1564..7501847726a 100644 --- a/config.w32 +++ b/config.w32 @@ -1,19 +1,18 @@ ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); -PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_btree.c'; +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c phpdbg_watch.c phpdbg_win.c phpdbg_btree.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; if (PHP_PHPDBG == "yes") { - /* build phpdbg binary */ SAPI('phpdbg', PHPDBG_SOURCES, PHPDBG_EXE); ADD_FLAG("LIBS_PHPDBG", "ws2_32.lib user32.lib"); + DEFINE("CFLAGS", configure_subst.item("CFLAGS") + " /EHa"); } if (PHP_PHPDBGS == "yes") { SAPI('phpdbgs', PHPDBG_SOURCES, PHPDBG_DLL, '/D PHP_PHPDBG_EXPORTS /I win32'); ADD_FLAG("LIBS_PHPDBGS", "ws2_32.lib user32.lib"); -} - - + DEFINE("CFLAGS", configure_subst.item("CFLAGS") + " /EHa"); +} \ No newline at end of file diff --git a/phpdbg.c b/phpdbg.c index b522b6cf39b..af3b75c95e3 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -#ifndef ZEND_SIGNALS +#if !defined(ZEND_SIGNALS) || defined(_WIN32) # include #endif #include "phpdbg.h" @@ -30,14 +30,6 @@ #include "phpdbg_set.h" #include "zend_alloc.h" -/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c */ -struct _zend_mm_heap { - int use_zend_alloc; - void *(*_malloc)(size_t); - void (*_free)(void*); - void *(*_realloc)(void*, size_t); -}; - /* {{{ remote console headers */ #ifndef _WIN32 # include @@ -818,7 +810,6 @@ int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*sock return SUCCESS; } /* }}} */ -#endif void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) { int is_handled = FAILURE; @@ -839,6 +830,7 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) { } } +#endif int main(int argc, char **argv) /* {{{ */ { @@ -877,11 +869,11 @@ int main(int argc, char **argv) /* {{{ */ void ***tsrm_ls; #endif +#ifndef _WIN32 struct sigaction signal_struct; signal_struct.sa_sigaction = phpdbg_signal_handler; signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; -#ifndef _WIN32 address = strdup("127.0.0.1"); socket[0] = -1; socket[1] = -1; @@ -1154,50 +1146,51 @@ phpdbg_main: phpdbg->ini_entries = ini_entries; if (phpdbg->startup(phpdbg) == SUCCESS) { - +#ifdef _WIN32 + EXCEPTION_POINTERS *xp; + __try { +#endif zend_mm_heap *mm_heap = zend_mm_set_heap(NULL TSRMLS_CC); if (!mm_heap->use_zend_alloc) { free(mm_heap); mm_heap = zend_mm_startup(); } PHPDBG_G(original_free_function) = mm_heap->_free; +#ifdef _WIN32 + phpdbg_win_set_mm_heap(mm_heap); +#else mm_heap->_free = phpdbg_watch_efree; +#endif zend_mm_set_heap(mm_heap TSRMLS_CC); zend_activate(TSRMLS_C); -#ifdef ZEND_SIGNALS +#if defined(ZEND_SIGNALS) && !defined(_WIN32) zend_try { zend_signal_activate(TSRMLS_C); } zend_end_try(); #endif -#ifdef ZEND_SIGNALS +#if defined(ZEND_SIGNALS) && !defined(_WIN32) zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); -#else +#elif !defined(_WIN32) sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); #endif /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ -#ifdef ZEND_SIGNALS -# ifndef _WIN32 +#if defined(ZEND_SIGNALS) && !defined(_WIN32) if (listen[0] < 0) { -# endif zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try(); -# ifndef _WIN32 } -# endif -#else -# ifndef _WIN32 +#elif !defined(_WIN32) if (listen[0] < 0) { -# endif +#endif signal(SIGINT, phpdbg_sigint_handler); #ifndef _WIN32 } -#endif #endif PG(modules_activated) = 0; @@ -1284,7 +1277,10 @@ phpdbg_main: } } +/* #ifndef for making compiler shutting up */ +#ifndef _WIN32 phpdbg_interact: +#endif /* phpdbg main() */ do { zend_try { @@ -1377,6 +1373,11 @@ phpdbg_out: } zend_end_try(); sapi_shutdown(); +#ifdef _WIN32 + } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { + // if !EXCEPTION_CONTINUE_EXECUTION + } + #endif } if (cleaning || remote) { diff --git a/phpdbg.h b/phpdbg.h index 4c2f2231ae6..3c4c88b23e0 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -39,7 +39,9 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" -#include "zend_signal.h" +#ifndef _WIN32 +# include "zend_signal.h" +#endif #include "SAPI.h" #include #include @@ -169,8 +171,10 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ +#ifndef _WIN32 struct sigaction old_sigsegv_signal; /* segv signal handler */ - +#endif + phpdbg_btree watchpoint_tree; /* tree with watchpoints */ HashTable watchpoints; /* watchpoints */ zend_llist watchlist_mem; /* triggered watchpoints */ @@ -196,4 +200,13 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ +/* the beginning (= the important part) of the _zend_mm_heap struct defined in Zend/zend_alloc.c + Needed for realizing watchpoints */ +struct _zend_mm_heap { + int use_zend_alloc; + void *(*_malloc)(size_t); + void (*_free)(void *); + void *(*_realloc)(void *, size_t); +}; + #endif /* PHPDBG_H */ diff --git a/phpdbg_btree.c b/phpdbg_btree.c index f3b6306a2a9..f6061354886 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -24,6 +24,11 @@ #define CHOOSE_BRANCH(n) \ branch = branch->branches[!!(n)]; +#ifdef _Win32 +# define emalloc malloc +# define efree free +#endif + /* depth in bits */ void phpdbg_btree_init(phpdbg_btree *tree, zend_ulong depth) { tree->depth = depth; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index f89b3277ad2..05805925131 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -23,12 +23,13 @@ #include "phpdbg_btree.h" #include "phpdbg_watch.h" #include "phpdbg_utils.h" -#include -#include +#ifndef _WIN32 +# include +# include +#endif ZEND_EXTERN_MODULE_GLOBALS(phpdbg); -long phpdbg_pagesize; typedef struct { void *page; @@ -40,13 +41,6 @@ typedef struct { #define MEMDUMP_SIZE(size) (sizeof(phpdbg_watch_memdump) - sizeof(void *) + (size)) -static zend_always_inline void *phpdbg_get_page_boundary(void *addr) { - return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); -} - -static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { - return (size_t)phpdbg_get_page_boundary(addr + size - 1) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; -} static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) { phpdbg_watchpoint_t *watch; @@ -285,7 +279,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { return ret; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, int i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { int ret = FAILURE; zend_bool new_index = 1; char *last_index; @@ -456,13 +450,23 @@ int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_delete_watchpoint TSRMLS_CC); } +#ifdef _WIN32 +int phpdbg_watchpoint_segfault_handler(void *addr TSRMLS_DC) { +#else int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC) { +#endif void *page; phpdbg_watch_memdump *dump; phpdbg_watchpoint_t *watch; size_t size; - watch = phpdbg_check_for_watchpoint(info->si_addr TSRMLS_CC); + watch = phpdbg_check_for_watchpoint( +#ifdef _WIN32 + addr +#else + info->si_addr +#endif + TSRMLS_CC); if (watch == NULL) { return FAILURE; @@ -506,12 +510,12 @@ static void phpdbg_watch_dtor(void *pDest) { static void phpdbg_watch_mem_dtor(void *llist_data) { phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data; - free(*(void **)llist_data); - /* Disble writing again */ if (dump->reenable_writing) { - mprotect(dump->page, dump->size, PROT_NONE | PROT_READ); + mprotect(dump->page, dump->size, PROT_READ); } + + free(*(void **)llist_data); } void phpdbg_setup_watchpoints(TSRMLS_D) { @@ -668,10 +672,10 @@ void phpdbg_watch_efree(void *ptr) { if (result) { phpdbg_watchpoint_t *watch = result->ptr; - if (watch->addr.ptr + watch->size > ptr) { + if ((size_t)watch->addr.ptr + watch->size > (size_t)ptr) { zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } } PHPDBG_G(original_free_function)(ptr); -} +} \ No newline at end of file diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 1aa3ad75b04..71402ae8035 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2013 The PHP Group | + | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -24,6 +24,10 @@ #include "TSRM.h" #include "phpdbg_cmd.h" +#ifdef _WIN32 +# include "phpdbg_win.h" +#endif + #define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name) /** @@ -76,7 +80,11 @@ struct _phpdbg_watchpoint_t { void phpdbg_setup_watchpoints(TSRMLS_D); +#ifndef _WIN32 int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context TSRMLS_DC); +#else +int phpdbg_watchpoint_segfault_handler(void *addr TSRMLS_DC); +#endif void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch); void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch); @@ -90,4 +98,15 @@ void phpdbg_list_watchpoints(TSRMLS_D); void phpdbg_watch_efree(void *ptr); -#endif + +long phpdbg_pagesize; + +static zend_always_inline void *phpdbg_get_page_boundary(void *addr) { + return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); +} + +static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) { + return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; +} + +#endif \ No newline at end of file diff --git a/phpdbg_win.c b/phpdbg_win.c new file mode 100644 index 00000000000..29f80449fa3 --- /dev/null +++ b/phpdbg_win.c @@ -0,0 +1,81 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "phpdbg.h" + +phpdbg_btree phpdbg_memory_tree; + +int mprotect(void *addr, size_t size, int protection) { + int var; + //printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-"); + return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var); +} + +size_t virtual_size(void *ptr) { + return (size_t)phpdbg_btree_find(&phpdbg_memory_tree, (zend_ulong)ptr)->ptr; +} + +void *virtual_malloc(size_t size) { + size_t real_size = phpdbg_get_total_page_size(NULL, size); + void *addr = VirtualAlloc(NULL, real_size, MEM_COMMIT, PAGE_READWRITE); + phpdbg_btree_insert(&phpdbg_memory_tree, (zend_ulong)addr, (void *)real_size); + return addr; +} + +void virtual_free(void *ptr) { + phpdbg_watch_efree(ptr); + VirtualFree(ptr, virtual_size(ptr), MEM_RELEASE); + phpdbg_btree_delete(&phpdbg_memory_tree, (zend_ulong)ptr); +} + +void *virtual_realloc(void *ptr, size_t size) { + void *ret; + size_t original_size = virtual_size(ptr); + + if (original_size >= size) { + return ptr; + } + + ret = virtual_malloc(size); + memcpy(ret, ptr, original_size); + virtual_free(ptr); + return ret; +} + +void phpdbg_win_set_mm_heap(zend_mm_heap *heap) { + phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8); + heap->_free = virtual_free; + heap->_realloc = virtual_realloc; + heap->_malloc = virtual_malloc; +} + +int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { + EXCEPTION_RECORD *xr = xp->ExceptionRecord; + CONTEXT *xc = xp->ContextRecord; + if(xr->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { + TSRMLS_FETCH(); + //printf("Watchpoint hit at: %p\n", xr->ExceptionInformation[1]); + if (phpdbg_watchpoint_segfault_handler((void *)xr->ExceptionInformation[1] TSRMLS_CC) == SUCCESS) { + return EXCEPTION_CONTINUE_EXECUTION; + } + } + return EXCEPTION_CONTINUE_SEARCH; +} \ No newline at end of file diff --git a/phpdbg_win.h b/phpdbg_win.h new file mode 100644 index 00000000000..da97c797b14 --- /dev/null +++ b/phpdbg_win.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2014 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_WIN_H +#define PHPDBG_WIN_H + +#include "winbase.h" +#include "windows.h" +#include "excpt.h" + +#define PROT_READ 1 +#define PROT_WRITE 2 + +int mprotect(void *addr, size_t size, int protection); + +void phpdbg_win_set_mm_heap(zend_mm_heap *heap); + +int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp); + +int __stdcall phpdbg_watch_set_segv_handler_asm(); + +#endif \ No newline at end of file From 98025a40b8b0a791b75fa6b330ed8d54c92da31c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 16 Mar 2014 20:04:08 +0100 Subject: [PATCH 087/137] Cleanup --- phpdbg.c | 11 ++++++----- phpdbg_win.h | 2 -- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index af3b75c95e3..12611e3ebe4 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1336,6 +1336,11 @@ phpdbg_out: } #endif +#ifdef _WIN32 + } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { + phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); + } +#endif #ifndef ZTS /* force cleanup of auto and core globals */ zend_hash_clean(CG(auto_globals)); @@ -1373,11 +1378,7 @@ phpdbg_out: } zend_end_try(); sapi_shutdown(); -#ifdef _WIN32 - } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { - // if !EXCEPTION_CONTINUE_EXECUTION - } - #endif + } if (cleaning || remote) { diff --git a/phpdbg_win.h b/phpdbg_win.h index da97c797b14..68c30527907 100644 --- a/phpdbg_win.h +++ b/phpdbg_win.h @@ -34,6 +34,4 @@ void phpdbg_win_set_mm_heap(zend_mm_heap *heap); int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp); -int __stdcall phpdbg_watch_set_segv_handler_asm(); - #endif \ No newline at end of file From f887960f9b282f1ac0b68f590849d0edb4ab9794 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 16 Mar 2014 22:37:33 +0100 Subject: [PATCH 088/137] removed some weird crash when freeing to early --- phpdbg.c | 19 +++++++++++-------- phpdbg.h | 6 ++++++ phpdbg_watch.c | 27 +++++++++++++++++++++------ phpdbg_win.c | 15 +++++++++++---- test.php | 2 ++ 5 files changed, 51 insertions(+), 18 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 12611e3ebe4..6bb52b0bbc2 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1151,15 +1151,17 @@ phpdbg_main: __try { #endif zend_mm_heap *mm_heap = zend_mm_set_heap(NULL TSRMLS_CC); +#if ZEND_DEBUG if (!mm_heap->use_zend_alloc) { - free(mm_heap); - mm_heap = zend_mm_startup(); + mm_heap->_malloc = malloc; + mm_heap->_realloc = realloc; + mm_heap->_free = free; +#endif + PHPDBG_G(original_free_function) = mm_heap->_free; + mm_heap->_free = phpdbg_watch_efree; + mm_heap->use_zend_alloc = 0; +#if ZEND_DEBUG } - PHPDBG_G(original_free_function) = mm_heap->_free; -#ifdef _WIN32 - phpdbg_win_set_mm_heap(mm_heap); -#else - mm_heap->_free = phpdbg_watch_efree; #endif zend_mm_set_heap(mm_heap TSRMLS_CC); @@ -1328,8 +1330,8 @@ phpdbg_interact: /* this is just helpful */ PG(report_memleaks) = 0; -phpdbg_out: #ifndef _WIN32 +phpdbg_out: if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) { PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED; goto phpdbg_interact; @@ -1340,6 +1342,7 @@ phpdbg_out: } __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) { phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly..."); } +phpdbg_out: #endif #ifndef ZTS /* force cleanup of auto and core globals */ diff --git a/phpdbg.h b/phpdbg.h index 3c4c88b23e0..ba59f1d3200 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -207,6 +207,12 @@ struct _zend_mm_heap { void *(*_malloc)(size_t); void (*_free)(void *); void *(*_realloc)(void *, size_t); + size_t free_bitmap; + size_t large_free_bitmap; + size_t block_size; + size_t compact_size; + zend_mm_segment *segments_list; + zend_mm_storage *storage; }; #endif /* PHPDBG_H */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 05805925131..1c4f6f895a3 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -503,7 +503,6 @@ static void phpdbg_watch_dtor(void *pDest) { free(watch->str); free(watch->name_in_parent); - efree(watch); } @@ -571,14 +570,19 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_notice("Breaking on watchpoint %s", watch->str); switch (watch->type) { - case WATCH_ON_ZVAL: + case WATCH_ON_ZVAL: { + int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1); phpdbg_write("Old value: "); - zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { + phpdbg_write("Value inaccessible, HashTable already destroyed"); + } else { + zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + } phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); /* check if zval was removed */ - if (((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1)) { + if (removed) { phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); @@ -606,9 +610,20 @@ remove_ht_watch: } break; - + } case WATCH_ON_HASHTABLE: +#ifdef ZEND_DEBUG + if (watch->addr.ht->inconsistent) { + phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str); + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + + reenable = 0; + + break; + } +#endif + elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); if (elementDiff) { if (elementDiff > 0) { @@ -668,7 +683,7 @@ void phpdbg_list_watchpoints(TSRMLS_D) { void phpdbg_watch_efree(void *ptr) { TSRMLS_FETCH(); phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr); - + if (result) { phpdbg_watchpoint_t *watch = result->ptr; diff --git a/phpdbg_win.c b/phpdbg_win.c index 29f80449fa3..e0180e14c36 100644 --- a/phpdbg_win.c +++ b/phpdbg_win.c @@ -25,7 +25,7 @@ phpdbg_btree phpdbg_memory_tree; int mprotect(void *addr, size_t size, int protection) { int var; - //printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-"); + printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-"); return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var); } @@ -33,7 +33,7 @@ size_t virtual_size(void *ptr) { return (size_t)phpdbg_btree_find(&phpdbg_memory_tree, (zend_ulong)ptr)->ptr; } -void *virtual_malloc(size_t size) { +/*void *virtual_malloc(size_t size) { size_t real_size = phpdbg_get_total_page_size(NULL, size); void *addr = VirtualAlloc(NULL, real_size, MEM_COMMIT, PAGE_READWRITE); phpdbg_btree_insert(&phpdbg_memory_tree, (zend_ulong)addr, (void *)real_size); @@ -58,15 +58,22 @@ void *virtual_realloc(void *ptr, size_t size) { memcpy(ret, ptr, original_size); virtual_free(ptr); return ret; -} +}*/ -void phpdbg_win_set_mm_heap(zend_mm_heap *heap) { +/*void phpdbg_win_set_mm_heap(zend_mm_heap *heap) { phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8); heap->_free = virtual_free; heap->_realloc = virtual_realloc; heap->_malloc = virtual_malloc; } +void phpdbg_win_set_mm_storage(zend_mm_storage *storage) { + phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8); + storage->_free = virtual_free; + storage->_realloc = virtual_realloc; + storage->_malloc = virtual_malloc; +}*/ + int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { EXCEPTION_RECORD *xr = xp->ExceptionRecord; CONTEXT *xc = xp->ContextRecord; diff --git a/test.php b/test.php index 20be79f8872..03cefd89338 100644 --- a/test.php +++ b/test.php @@ -72,3 +72,5 @@ $test = $obj->a; $obj->a += 2; $test -= 2; + +unset($obj); From 1401314a1b707f74ffa1e864c1c5c2fcb372e020 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 17 Mar 2014 06:19:14 -0400 Subject: [PATCH 089/137] Fixed one major bug in phpdbg_btree_delete There is some bug when arrays/property tables are deleted: the children are not notified (Considering now to overwrite the dtor of the array) --- phpdbg_btree.c | 7 ++++--- phpdbg_watch.c | 28 +++++++++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/phpdbg_btree.c b/phpdbg_btree.c index f6061354886..9eba9823de1 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -83,7 +83,7 @@ phpdbg_btree_result *phpdbg_btree_find_closest(phpdbg_btree *tree, zend_ulong id } /* reset state */ branch = tree->branch; - i = sizeof(void *) * 8 - 1; + i = tree->depth - 1; /* follow branch according to bits in idx until the last lower branch before the impossible branch */ do { CHOOSE_BRANCH((idx >> i) % 2 == 1 && branch->branches[1]); @@ -200,14 +200,15 @@ check_branch_existence: tree->branch = NULL; } else { if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) { + phpdbg_btree_branch *original_branch = last_dual_branch->branches[!last_dual_branch_branch]; + memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], i_last_dual_branch * sizeof(phpdbg_btree_branch)); efree(last_dual_branch->branches[!last_dual_branch_branch]); last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1; branch = last_dual_branch->branches[!last_dual_branch_branch]; for (i = i_last_dual_branch; i--;) { - branch->branches[!!branch->branches[1]] = last_dual_branch + i_last_dual_branch - i + 1; - branch = branch->branches[!!branch->branches[1]]; + branch = (branch->branches[branch->branches[1] == ++original_branch] = last_dual_branch + i_last_dual_branch - i + 1); } } else { efree(last_dual_branch->branches[last_dual_branch_branch]); diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 1c4f6f895a3..f2f127b61eb 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -66,11 +66,12 @@ static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int acce /* pagesize is assumed to be in the range of 2^x */ m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access); - +/* if (m == FAILURE) { phpdbg_error("Unable to (un)set watchpoint (mprotect() failed)"); zend_bailout(); } +*/ } static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { @@ -538,7 +539,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong)dump->page, (zend_ulong)dump->page + dump->size); phpdbg_btree_result *result, *htresult; int elementDiff; - void **curTest; + void *curTest; dump->reenable_writing = 0; @@ -548,15 +549,24 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { char reenable = 1; /* Test if the zval was separated and if necessary move the watchpoint */ - if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len, (void **) &curTest) == SUCCESS) { + if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1, &curTest) == SUCCESS) { if (watch->type == WATCH_ON_HASHTABLE) { - curTest = (void **)&Z_ARRVAL_PP((zval **)curTest); + switch (Z_TYPE_PP((zval **)curTest)) { + case IS_ARRAY: + curTest = (void *)Z_ARRVAL_PP((zval **)curTest); + break; + case IS_OBJECT: + curTest = (void *)Z_OBJPROP_PP((zval **)curTest); + break; + } + } else { + curTest = *(void **)curTest; } - if (*curTest != watch->addr.ptr) { + if (curTest != watch->addr.ptr) { phpdbg_deactivate_watchpoint(watch TSRMLS_CC); phpdbg_remove_watchpoint(watch TSRMLS_CC); - watch->addr.ptr = *curTest; + watch->addr.ptr = curTest; phpdbg_store_watchpoint(watch TSRMLS_CC); phpdbg_activate_watchpoint(watch TSRMLS_CC); @@ -588,7 +598,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { reenable = 0; - if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY) { + if (Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) { goto remove_ht_watch; } @@ -599,7 +609,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); - if (Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) { + if ((Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { break; } @@ -693,4 +703,4 @@ void phpdbg_watch_efree(void *ptr) { } PHPDBG_G(original_free_function)(ptr); -} \ No newline at end of file +} From 7b0219212daa26a71ec66d7e7fc69f179819aa19 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 22 Mar 2014 09:39:39 -0400 Subject: [PATCH 090/137] Fixed possible segmentation fault upon unset with watchpoints --- phpdbg.h | 1 + phpdbg_watch.c | 61 ++++++++++++++++++++++++++++++++++++-------------- phpdbg_watch.h | 3 +-- phpdbg_win.c | 44 +----------------------------------- 4 files changed, 47 insertions(+), 62 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index ba59f1d3200..c2653155979 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -176,6 +176,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) #endif phpdbg_btree watchpoint_tree; /* tree with watchpoints */ + phpdbg_btree watch_HashTables; /* tree with original dtors of watchpoints */ HashTable watchpoints; /* watchpoints */ zend_llist watchlist_mem; /* triggered watchpoints */ zend_bool watchpoint_hit; /* a watchpoint was hit */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index f2f127b61eb..acbbffdb691 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -66,12 +66,6 @@ static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int acce /* pagesize is assumed to be in the range of 2^x */ m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access); -/* - if (m == FAILURE) { - phpdbg_error("Unable to (un)set watchpoint (mprotect() failed)"); - zend_bailout(); - } -*/ } static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { @@ -93,7 +87,6 @@ static inline void phpdbg_remove_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) { watch->addr.ptr = addr; watch->size = size; - watch->type = WATCH_ON_PTR; } void phpdbg_create_zval_watchpoint(zval *zv, phpdbg_watchpoint_t *watch) { @@ -106,12 +99,19 @@ void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) { watch->type = WATCH_ON_HASHTABLE; } +void phpdbg_watch_HashTable_dtor(zval **ptr); + static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { watch->flags |= PHPDBG_WATCH_SIMPLE; phpdbg_store_watchpoint(watch TSRMLS_CC); zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL); + if (watch->type == WATCH_ON_ZVAL) { + phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong)watch->parent_container, watch->parent_container->pDestructor); + watch->parent_container->pDestructor = (dtor_func_t)phpdbg_watch_HashTable_dtor; + } + phpdbg_activate_watchpoint(watch TSRMLS_CC); return SUCCESS; @@ -183,7 +183,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ } new_watch->str = NULL; - new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", (int)new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); phpdbg_create_zval_watchpoint(*zv, new_watch); phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); @@ -198,7 +198,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ new_watch->name_in_parent = zend_strndup(watch->name_in_parent, watch->name_in_parent_len); new_watch->name_in_parent_len = watch->name_in_parent_len; new_watch->str = NULL; - new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", watch->str_len, watch->str); + new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", (int)watch->str_len, watch->str); new_watch->flags = PHPDBG_WATCH_RECURSIVE; phpdbg_create_ht_watchpoint(ht, new_watch); @@ -229,9 +229,9 @@ static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch TSRMLS_ zend_hash_get_current_key_zval_ex(ht, &key, &position); str = NULL; if (Z_TYPE(key) == IS_STRING) { - str_len = asprintf(&str, "%.*s%s%.*s%s", watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_STRLEN(key), Z_STRVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + str_len = asprintf(&str, "%.*s%s%.*s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_STRLEN(key), Z_STRVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); } else { - str_len = asprintf(&str, "%.*s%s%i%s", watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + str_len = asprintf(&str, "%.*s%s%li%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); } if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) { @@ -332,7 +332,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par zend_hash_get_current_key_zval_ex(parent, key, &position); convert_to_string(key); watch->str = malloc(i + Z_STRLEN_P(key) + 2); - watch->str_len = sprintf(watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); + watch->str_len = sprintf(watch->str, "%.*s%.*s%s", (int)i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); efree(key); watch->name_in_parent = zend_strndup(last_index, index_len); watch->name_in_parent_len = index_len; @@ -353,7 +353,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par char last_chr = last_index[index_len]; last_index[index_len] = 0; if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { - phpdbg_error("%.*s is undefined", i, input); + phpdbg_error("%.*s is undefined", (int)i, input); return FAILURE; } last_index[index_len] = last_chr; @@ -373,7 +373,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par } else if (Z_TYPE_PP(zv) == IS_ARRAY) { parent = Z_ARRVAL_PP(zv); } else { - phpdbg_error("%.*s is nor an array nor an object", i, input); + phpdbg_error("%.*s is nor an array nor an object", (int)i, input); return FAILURE; } index_len = 0; @@ -435,6 +435,26 @@ PHPDBG_WATCH(array) /* {{{ */ return SUCCESS; } /* }}} */ +void phpdbg_watch_HashTable_dtor(zval **zv) { + phpdbg_btree_result *result; + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) { + phpdbg_watchpoint_t *watch = result->ptr; + + PHPDBG_G(watchpoint_hit) = 1; + + phpdbg_notice("%.*s was removed, removing watchpoint%s", watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); + + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_delete_watchpoint_recursive(watch TSRMLS_CC); + } else { + zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); + } + } + + zval_ptr_dtor_wrapper(zv); +} + + int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { return SUCCESS; @@ -531,6 +551,7 @@ void phpdbg_setup_watchpoints(TSRMLS_D) { zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1); phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8); + phpdbg_btree_init(&PHPDBG_G(watch_HashTables), sizeof(void *) * 8); _zend_hash_init(&PHPDBG_G(watchpoints), 8, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC); } @@ -548,6 +569,10 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page); char reenable = 1; + if (watch->addr.ptr < dump->page || watch->addr.ptr + watch->size > dump->page + dump->size) { + continue; + } + /* Test if the zval was separated and if necessary move the watchpoint */ if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1, &curTest) == SUCCESS) { if (watch->type == WATCH_ON_HASHTABLE) { @@ -661,13 +686,12 @@ remove_ht_watch: int phpdbg_print_changed_zvals(TSRMLS_D) { zend_llist_position pos; phpdbg_watch_memdump **dump; + int ret; if (zend_llist_count(&PHPDBG_G(watchlist_mem)) == 0) { return FAILURE; } - PHPDBG_G(watchpoint_hit) = 0; - dump = (phpdbg_watch_memdump **)zend_llist_get_last_ex(&PHPDBG_G(watchlist_mem), &pos); do { @@ -676,7 +700,10 @@ int phpdbg_print_changed_zvals(TSRMLS_D) { zend_llist_clean(&PHPDBG_G(watchlist_mem)); - return PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; + ret = PHPDBG_G(watchpoint_hit)?SUCCESS:FAILURE; + PHPDBG_G(watchpoint_hit) = 0; + + return ret; } void phpdbg_list_watchpoints(TSRMLS_D) { diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 71402ae8035..a5dac0effab 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -52,7 +52,6 @@ static const phpdbg_command_t phpdbg_watch_commands[] = { typedef enum { WATCH_ON_ZVAL, WATCH_ON_HASHTABLE, - WATCH_ON_PTR } phpdbg_watchtype; @@ -109,4 +108,4 @@ static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t s return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize; } -#endif \ No newline at end of file +#endif diff --git a/phpdbg_win.c b/phpdbg_win.c index e0180e14c36..55d4b0f94d1 100644 --- a/phpdbg_win.c +++ b/phpdbg_win.c @@ -25,7 +25,6 @@ phpdbg_btree phpdbg_memory_tree; int mprotect(void *addr, size_t size, int protection) { int var; - printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-"); return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var); } @@ -33,47 +32,6 @@ size_t virtual_size(void *ptr) { return (size_t)phpdbg_btree_find(&phpdbg_memory_tree, (zend_ulong)ptr)->ptr; } -/*void *virtual_malloc(size_t size) { - size_t real_size = phpdbg_get_total_page_size(NULL, size); - void *addr = VirtualAlloc(NULL, real_size, MEM_COMMIT, PAGE_READWRITE); - phpdbg_btree_insert(&phpdbg_memory_tree, (zend_ulong)addr, (void *)real_size); - return addr; -} - -void virtual_free(void *ptr) { - phpdbg_watch_efree(ptr); - VirtualFree(ptr, virtual_size(ptr), MEM_RELEASE); - phpdbg_btree_delete(&phpdbg_memory_tree, (zend_ulong)ptr); -} - -void *virtual_realloc(void *ptr, size_t size) { - void *ret; - size_t original_size = virtual_size(ptr); - - if (original_size >= size) { - return ptr; - } - - ret = virtual_malloc(size); - memcpy(ret, ptr, original_size); - virtual_free(ptr); - return ret; -}*/ - -/*void phpdbg_win_set_mm_heap(zend_mm_heap *heap) { - phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8); - heap->_free = virtual_free; - heap->_realloc = virtual_realloc; - heap->_malloc = virtual_malloc; -} - -void phpdbg_win_set_mm_storage(zend_mm_storage *storage) { - phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8); - storage->_free = virtual_free; - storage->_realloc = virtual_realloc; - storage->_malloc = virtual_malloc; -}*/ - int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { EXCEPTION_RECORD *xr = xp->ExceptionRecord; CONTEXT *xc = xp->ContextRecord; @@ -85,4 +43,4 @@ int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { } } return EXCEPTION_CONTINUE_SEARCH; -} \ No newline at end of file +} From bd2305f1d2b69eb05c0929ab9cf2189e5e9bc67e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 22 Mar 2014 21:27:25 -0400 Subject: [PATCH 091/137] Fixed possible duplication of watchpoints output --- phpdbg_prompt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 51f62634972..70d567d5dc4 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1093,6 +1093,8 @@ out: PHPDBG_G(flags) &= ~PHPDBG_IS_INTERACTIVE; + phpdbg_print_changed_zvals(TSRMLS_C); + return ret; } /* }}} */ From 30fab784dc161de509674eb45640cf13f5d7d094 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 23 Mar 2014 14:57:25 +0100 Subject: [PATCH 092/137] Fixed TSRM build --- phpdbg_watch.c | 4 +++- phpdbg_watch.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index acbbffdb691..6b1a42ddbe3 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -436,13 +436,15 @@ PHPDBG_WATCH(array) /* {{{ */ } /* }}} */ void phpdbg_watch_HashTable_dtor(zval **zv) { + TSRMLS_FETCH(); + phpdbg_btree_result *result; if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) { phpdbg_watchpoint_t *watch = result->ptr; PHPDBG_G(watchpoint_hit) = 1; - phpdbg_notice("%.*s was removed, removing watchpoint%s", watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); + phpdbg_notice("%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); if (watch->flags & PHPDBG_WATCH_RECURSIVE) { phpdbg_delete_watchpoint_recursive(watch TSRMLS_CC); diff --git a/phpdbg_watch.h b/phpdbg_watch.h index a5dac0effab..56dd068e2fa 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -98,7 +98,7 @@ void phpdbg_list_watchpoints(TSRMLS_D); void phpdbg_watch_efree(void *ptr); -long phpdbg_pagesize; +static long phpdbg_pagesize; static zend_always_inline void *phpdbg_get_page_boundary(void *addr) { return (void *)((size_t)addr & ~(phpdbg_pagesize - 1)); From e55bbd47afeb100b0a50dd36912942c33409f0a3 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 24 Mar 2014 14:46:14 +0100 Subject: [PATCH 093/137] Use the internal zend_get_opcode_name() function Requires now >=5.4.24 or >=5.5.8 or >=5.6 --- phpdbg_opcode.c | 179 +----------------------------------------------- 1 file changed, 2 insertions(+), 177 deletions(-) diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 50073eb22bb..55fb03ed1a3 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -183,181 +183,6 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ { -#define CASE(s) case s: return #s - switch (opcode) { - CASE(ZEND_NOP); - CASE(ZEND_ADD); - CASE(ZEND_SUB); - CASE(ZEND_MUL); - CASE(ZEND_DIV); - CASE(ZEND_MOD); - CASE(ZEND_SL); - CASE(ZEND_SR); - CASE(ZEND_CONCAT); - CASE(ZEND_BW_OR); - CASE(ZEND_BW_AND); - CASE(ZEND_BW_XOR); - CASE(ZEND_BW_NOT); - CASE(ZEND_BOOL_NOT); - CASE(ZEND_BOOL_XOR); - CASE(ZEND_IS_IDENTICAL); - CASE(ZEND_IS_NOT_IDENTICAL); - CASE(ZEND_IS_EQUAL); - CASE(ZEND_IS_NOT_EQUAL); - CASE(ZEND_IS_SMALLER); - CASE(ZEND_IS_SMALLER_OR_EQUAL); - CASE(ZEND_CAST); - CASE(ZEND_QM_ASSIGN); - CASE(ZEND_ASSIGN_ADD); - CASE(ZEND_ASSIGN_SUB); - CASE(ZEND_ASSIGN_MUL); - CASE(ZEND_ASSIGN_DIV); - CASE(ZEND_ASSIGN_MOD); - CASE(ZEND_ASSIGN_SL); - CASE(ZEND_ASSIGN_SR); - CASE(ZEND_ASSIGN_CONCAT); - CASE(ZEND_ASSIGN_BW_OR); - CASE(ZEND_ASSIGN_BW_AND); - CASE(ZEND_ASSIGN_BW_XOR); - CASE(ZEND_PRE_INC); - CASE(ZEND_PRE_DEC); - CASE(ZEND_POST_INC); - CASE(ZEND_POST_DEC); - CASE(ZEND_ASSIGN); - CASE(ZEND_ASSIGN_REF); - CASE(ZEND_ECHO); - CASE(ZEND_PRINT); - CASE(ZEND_JMP); - CASE(ZEND_JMPZ); - CASE(ZEND_JMPNZ); - CASE(ZEND_JMPZNZ); - CASE(ZEND_JMPZ_EX); - CASE(ZEND_JMPNZ_EX); - CASE(ZEND_CASE); - CASE(ZEND_SWITCH_FREE); - CASE(ZEND_BRK); - CASE(ZEND_CONT); - CASE(ZEND_BOOL); - CASE(ZEND_INIT_STRING); - CASE(ZEND_ADD_CHAR); - CASE(ZEND_ADD_STRING); - CASE(ZEND_ADD_VAR); - CASE(ZEND_BEGIN_SILENCE); - CASE(ZEND_END_SILENCE); - CASE(ZEND_INIT_FCALL_BY_NAME); - CASE(ZEND_DO_FCALL); - CASE(ZEND_DO_FCALL_BY_NAME); - CASE(ZEND_RETURN); - CASE(ZEND_RECV); - CASE(ZEND_RECV_INIT); - CASE(ZEND_SEND_VAL); - CASE(ZEND_SEND_VAR); - CASE(ZEND_SEND_REF); - CASE(ZEND_NEW); - CASE(ZEND_INIT_NS_FCALL_BY_NAME); - CASE(ZEND_FREE); - CASE(ZEND_INIT_ARRAY); - CASE(ZEND_ADD_ARRAY_ELEMENT); - CASE(ZEND_INCLUDE_OR_EVAL); - CASE(ZEND_UNSET_VAR); - CASE(ZEND_UNSET_DIM); - CASE(ZEND_UNSET_OBJ); - CASE(ZEND_FE_RESET); - CASE(ZEND_FE_FETCH); - CASE(ZEND_EXIT); - CASE(ZEND_FETCH_R); - CASE(ZEND_FETCH_DIM_R); - CASE(ZEND_FETCH_OBJ_R); - CASE(ZEND_FETCH_W); - CASE(ZEND_FETCH_DIM_W); - CASE(ZEND_FETCH_OBJ_W); - CASE(ZEND_FETCH_RW); - CASE(ZEND_FETCH_DIM_RW); - CASE(ZEND_FETCH_OBJ_RW); - CASE(ZEND_FETCH_IS); - CASE(ZEND_FETCH_DIM_IS); - CASE(ZEND_FETCH_OBJ_IS); - CASE(ZEND_FETCH_FUNC_ARG); - CASE(ZEND_FETCH_DIM_FUNC_ARG); - CASE(ZEND_FETCH_OBJ_FUNC_ARG); - CASE(ZEND_FETCH_UNSET); - CASE(ZEND_FETCH_DIM_UNSET); - CASE(ZEND_FETCH_OBJ_UNSET); - CASE(ZEND_FETCH_DIM_TMP_VAR); - CASE(ZEND_FETCH_CONSTANT); - CASE(ZEND_GOTO); - CASE(ZEND_EXT_STMT); - CASE(ZEND_EXT_FCALL_BEGIN); - CASE(ZEND_EXT_FCALL_END); - CASE(ZEND_EXT_NOP); - CASE(ZEND_TICKS); - CASE(ZEND_SEND_VAR_NO_REF); - CASE(ZEND_CATCH); - CASE(ZEND_THROW); - CASE(ZEND_FETCH_CLASS); - CASE(ZEND_CLONE); - CASE(ZEND_RETURN_BY_REF); - CASE(ZEND_INIT_METHOD_CALL); - CASE(ZEND_INIT_STATIC_METHOD_CALL); - CASE(ZEND_ISSET_ISEMPTY_VAR); - CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ); - CASE(ZEND_PRE_INC_OBJ); - CASE(ZEND_PRE_DEC_OBJ); - CASE(ZEND_POST_INC_OBJ); - CASE(ZEND_POST_DEC_OBJ); - CASE(ZEND_ASSIGN_OBJ); - CASE(ZEND_INSTANCEOF); - CASE(ZEND_DECLARE_CLASS); - CASE(ZEND_DECLARE_INHERITED_CLASS); - CASE(ZEND_DECLARE_FUNCTION); - CASE(ZEND_RAISE_ABSTRACT_ERROR); - CASE(ZEND_DECLARE_CONST); - CASE(ZEND_ADD_INTERFACE); - CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED); - CASE(ZEND_VERIFY_ABSTRACT_CLASS); - CASE(ZEND_ASSIGN_DIM); - CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ); - CASE(ZEND_HANDLE_EXCEPTION); - CASE(ZEND_USER_OPCODE); -#ifdef ZEND_JMP_SET - CASE(ZEND_JMP_SET); -#endif - CASE(ZEND_DECLARE_LAMBDA_FUNCTION); -#ifdef ZEND_ADD_TRAIT - CASE(ZEND_ADD_TRAIT); -#endif -#ifdef ZEND_BIND_TRAITS - CASE(ZEND_BIND_TRAITS); -#endif -#ifdef ZEND_SEPARATE - CASE(ZEND_SEPARATE); -#endif -#ifdef ZEND_QM_ASSIGN_VAR - CASE(ZEND_QM_ASSIGN_VAR); -#endif -#ifdef ZEND_JMP_SET_VAR - CASE(ZEND_JMP_SET_VAR); -#endif -#ifdef ZEND_DISCARD_EXCEPTION - CASE(ZEND_DISCARD_EXCEPTION); -#endif -#ifdef ZEND_YIELD - CASE(ZEND_YIELD); -#endif -#ifdef ZEND_GENERATOR_RETURN - CASE(ZEND_GENERATOR_RETURN); -#endif -#ifdef ZEND_FAST_CALL - CASE(ZEND_FAST_CALL); -#endif -#ifdef ZEND_FAST_RET - CASE(ZEND_FAST_RET); -#endif -#ifdef ZEND_RECV_VARIADIC - CASE(ZEND_RECV_VARIADIC); -#endif - CASE(ZEND_OP_DATA); - default: - return "UNKNOWN"; - } + const char *ret = zend_get_opcode_name(opcode); + return ret?ret:"UNKNOWN"; } /* }}} */ From fcacee059599bb2ac147bc4e4c48f1300cdd04f9 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 3 Apr 2014 19:34:08 +0000 Subject: [PATCH 094/137] Fixed deleting watchpoints (plus error in btree_delete) --- phpdbg_btree.c | 2 +- phpdbg_watch.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/phpdbg_btree.c b/phpdbg_btree.c index 9eba9823de1..8fc2561e047 100644 --- a/phpdbg_btree.c +++ b/phpdbg_btree.c @@ -202,7 +202,7 @@ check_branch_existence: if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) { phpdbg_btree_branch *original_branch = last_dual_branch->branches[!last_dual_branch_branch]; - memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], i_last_dual_branch * sizeof(phpdbg_btree_branch)); + memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], (i_last_dual_branch + 1) * sizeof(phpdbg_btree_branch)); efree(last_dual_branch->branches[!last_dual_branch_branch]); last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 6b1a42ddbe3..50fa3927396 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -208,12 +208,12 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ return SUCCESS; } -static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) { +static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_bool user_request TSRMLS_DC) { if (watch->type == WATCH_ON_HASHTABLE || (watch->type == WATCH_ON_ZVAL && (Z_TYPE_P(watch->addr.zv) == IS_ARRAY || Z_TYPE_P(watch->addr.zv) == IS_OBJECT))) { HashTable *ht; phpdbg_btree_result *result; - if (watch->type == WATCH_ON_HASHTABLE) { + if (watch->type == WATCH_ON_HASHTABLE && user_request) { HashPosition position; zval **zv; zval key; @@ -235,7 +235,7 @@ static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch TSRMLS_ } if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) { - phpdbg_delete_watchpoint_recursive(*watchpoint TSRMLS_CC); + phpdbg_delete_watchpoint_recursive(*watchpoint, 1 TSRMLS_CC); } } } else { @@ -249,7 +249,7 @@ static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch TSRMLS_ } if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) ht))) { - phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr TSRMLS_CC); + phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr, user_request TSRMLS_CC); } } } @@ -269,7 +269,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { watch = result->ptr; if (watch->flags & PHPDBG_WATCH_RECURSIVE) { - ret = phpdbg_delete_watchpoint_recursive(watch TSRMLS_CC); + ret = phpdbg_delete_watchpoint_recursive(watch, 1 TSRMLS_CC); } else { ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } @@ -447,7 +447,7 @@ void phpdbg_watch_HashTable_dtor(zval **zv) { phpdbg_notice("%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE)?" recursively":""); if (watch->flags & PHPDBG_WATCH_RECURSIVE) { - phpdbg_delete_watchpoint_recursive(watch TSRMLS_CC); + phpdbg_delete_watchpoint_recursive(watch, 0 TSRMLS_CC); } else { zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } From 9d72a84f06ecebde47842540f51a6ea601b603ef Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 3 Apr 2014 19:53:58 +0000 Subject: [PATCH 095/137] Add array watchpoints if recursive zval watchpoint changed + WS --- phpdbg_watch.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 50fa3927396..a1bb742cd62 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -131,7 +131,7 @@ static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) return FAILURE; } - phpdbg_create_ht_watchpoint(Z_ARRVAL_P(watch->addr.zv), watch); + phpdbg_create_ht_watchpoint(ht, watch); phpdbg_create_watchpoint(watch TSRMLS_CC); @@ -439,6 +439,9 @@ void phpdbg_watch_HashTable_dtor(zval **zv) { TSRMLS_FETCH(); phpdbg_btree_result *result; + zval_ptr_dtor_wrapper(zv); + + if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) { phpdbg_watchpoint_t *watch = result->ptr; @@ -452,8 +455,6 @@ void phpdbg_watch_HashTable_dtor(zval **zv) { zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len); } } - - zval_ptr_dtor_wrapper(zv); } @@ -609,7 +610,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { switch (watch->type) { case WATCH_ON_ZVAL: { int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1); - + phpdbg_write("Old value: "); if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { phpdbg_write("Value inaccessible, HashTable already destroyed"); @@ -636,6 +637,13 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *)oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { + /* add new watchpoints if necessary */ + if (watch->flags & PHPDBG_WATCH_RECURSIVE) { + phpdbg_create_recursive_watchpoint(watch TSRMLS_CC); + } + } + if ((Z_TYPE_P((zval *)oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *)oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { break; } @@ -645,7 +653,7 @@ remove_ht_watch: htwatch = htresult->ptr; zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len); } - + break; } case WATCH_ON_HASHTABLE: @@ -660,7 +668,7 @@ remove_ht_watch: break; } #endif - + elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht); if (elementDiff) { if (elementDiff > 0) { @@ -722,7 +730,7 @@ void phpdbg_list_watchpoints(TSRMLS_D) { void phpdbg_watch_efree(void *ptr) { TSRMLS_FETCH(); phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr); - + if (result) { phpdbg_watchpoint_t *watch = result->ptr; From 48bcaf2e72ac66a713996a369e05cc725ca58e69 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Apr 2014 18:00:33 +0200 Subject: [PATCH 096/137] Retain full compability for all micro versions since PHP 5.4 --- phpdbg_opcode.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c index 55fb03ed1a3..6b13625fc14 100644 --- a/phpdbg_opcode.c +++ b/phpdbg_opcode.c @@ -183,6 +183,186 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ { +#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO +#define CASE(s) case s: return #s + switch (opcode) { + CASE(ZEND_NOP); + CASE(ZEND_ADD); + CASE(ZEND_SUB); + CASE(ZEND_MUL); + CASE(ZEND_DIV); + CASE(ZEND_MOD); + CASE(ZEND_SL); + CASE(ZEND_SR); + CASE(ZEND_CONCAT); + CASE(ZEND_BW_OR); + CASE(ZEND_BW_AND); + CASE(ZEND_BW_XOR); + CASE(ZEND_BW_NOT); + CASE(ZEND_BOOL_NOT); + CASE(ZEND_BOOL_XOR); + CASE(ZEND_IS_IDENTICAL); + CASE(ZEND_IS_NOT_IDENTICAL); + CASE(ZEND_IS_EQUAL); + CASE(ZEND_IS_NOT_EQUAL); + CASE(ZEND_IS_SMALLER); + CASE(ZEND_IS_SMALLER_OR_EQUAL); + CASE(ZEND_CAST); + CASE(ZEND_QM_ASSIGN); + CASE(ZEND_ASSIGN_ADD); + CASE(ZEND_ASSIGN_SUB); + CASE(ZEND_ASSIGN_MUL); + CASE(ZEND_ASSIGN_DIV); + CASE(ZEND_ASSIGN_MOD); + CASE(ZEND_ASSIGN_SL); + CASE(ZEND_ASSIGN_SR); + CASE(ZEND_ASSIGN_CONCAT); + CASE(ZEND_ASSIGN_BW_OR); + CASE(ZEND_ASSIGN_BW_AND); + CASE(ZEND_ASSIGN_BW_XOR); + CASE(ZEND_PRE_INC); + CASE(ZEND_PRE_DEC); + CASE(ZEND_POST_INC); + CASE(ZEND_POST_DEC); + CASE(ZEND_ASSIGN); + CASE(ZEND_ASSIGN_REF); + CASE(ZEND_ECHO); + CASE(ZEND_PRINT); + CASE(ZEND_JMP); + CASE(ZEND_JMPZ); + CASE(ZEND_JMPNZ); + CASE(ZEND_JMPZNZ); + CASE(ZEND_JMPZ_EX); + CASE(ZEND_JMPNZ_EX); + CASE(ZEND_CASE); + CASE(ZEND_SWITCH_FREE); + CASE(ZEND_BRK); + CASE(ZEND_CONT); + CASE(ZEND_BOOL); + CASE(ZEND_INIT_STRING); + CASE(ZEND_ADD_CHAR); + CASE(ZEND_ADD_STRING); + CASE(ZEND_ADD_VAR); + CASE(ZEND_BEGIN_SILENCE); + CASE(ZEND_END_SILENCE); + CASE(ZEND_INIT_FCALL_BY_NAME); + CASE(ZEND_DO_FCALL); + CASE(ZEND_DO_FCALL_BY_NAME); + CASE(ZEND_RETURN); + CASE(ZEND_RECV); + CASE(ZEND_RECV_INIT); + CASE(ZEND_SEND_VAL); + CASE(ZEND_SEND_VAR); + CASE(ZEND_SEND_REF); + CASE(ZEND_NEW); + CASE(ZEND_INIT_NS_FCALL_BY_NAME); + CASE(ZEND_FREE); + CASE(ZEND_INIT_ARRAY); + CASE(ZEND_ADD_ARRAY_ELEMENT); + CASE(ZEND_INCLUDE_OR_EVAL); + CASE(ZEND_UNSET_VAR); + CASE(ZEND_UNSET_DIM); + CASE(ZEND_UNSET_OBJ); + CASE(ZEND_FE_RESET); + CASE(ZEND_FE_FETCH); + CASE(ZEND_EXIT); + CASE(ZEND_FETCH_R); + CASE(ZEND_FETCH_DIM_R); + CASE(ZEND_FETCH_OBJ_R); + CASE(ZEND_FETCH_W); + CASE(ZEND_FETCH_DIM_W); + CASE(ZEND_FETCH_OBJ_W); + CASE(ZEND_FETCH_RW); + CASE(ZEND_FETCH_DIM_RW); + CASE(ZEND_FETCH_OBJ_RW); + CASE(ZEND_FETCH_IS); + CASE(ZEND_FETCH_DIM_IS); + CASE(ZEND_FETCH_OBJ_IS); + CASE(ZEND_FETCH_FUNC_ARG); + CASE(ZEND_FETCH_DIM_FUNC_ARG); + CASE(ZEND_FETCH_OBJ_FUNC_ARG); + CASE(ZEND_FETCH_UNSET); + CASE(ZEND_FETCH_DIM_UNSET); + CASE(ZEND_FETCH_OBJ_UNSET); + CASE(ZEND_FETCH_DIM_TMP_VAR); + CASE(ZEND_FETCH_CONSTANT); + CASE(ZEND_GOTO); + CASE(ZEND_EXT_STMT); + CASE(ZEND_EXT_FCALL_BEGIN); + CASE(ZEND_EXT_FCALL_END); + CASE(ZEND_EXT_NOP); + CASE(ZEND_TICKS); + CASE(ZEND_SEND_VAR_NO_REF); + CASE(ZEND_CATCH); + CASE(ZEND_THROW); + CASE(ZEND_FETCH_CLASS); + CASE(ZEND_CLONE); + CASE(ZEND_RETURN_BY_REF); + CASE(ZEND_INIT_METHOD_CALL); + CASE(ZEND_INIT_STATIC_METHOD_CALL); + CASE(ZEND_ISSET_ISEMPTY_VAR); + CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ); + CASE(ZEND_PRE_INC_OBJ); + CASE(ZEND_PRE_DEC_OBJ); + CASE(ZEND_POST_INC_OBJ); + CASE(ZEND_POST_DEC_OBJ); + CASE(ZEND_ASSIGN_OBJ); + CASE(ZEND_INSTANCEOF); + CASE(ZEND_DECLARE_CLASS); + CASE(ZEND_DECLARE_INHERITED_CLASS); + CASE(ZEND_DECLARE_FUNCTION); + CASE(ZEND_RAISE_ABSTRACT_ERROR); + CASE(ZEND_DECLARE_CONST); + CASE(ZEND_ADD_INTERFACE); + CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED); + CASE(ZEND_VERIFY_ABSTRACT_CLASS); + CASE(ZEND_ASSIGN_DIM); + CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ); + CASE(ZEND_HANDLE_EXCEPTION); + CASE(ZEND_USER_OPCODE); +#ifdef ZEND_JMP_SET + CASE(ZEND_JMP_SET); +#endif + CASE(ZEND_DECLARE_LAMBDA_FUNCTION); +#ifdef ZEND_ADD_TRAIT + CASE(ZEND_ADD_TRAIT); +#endif +#ifdef ZEND_BIND_TRAITS + CASE(ZEND_BIND_TRAITS); +#endif +#ifdef ZEND_SEPARATE + CASE(ZEND_SEPARATE); +#endif +#ifdef ZEND_QM_ASSIGN_VAR + CASE(ZEND_QM_ASSIGN_VAR); +#endif +#ifdef ZEND_JMP_SET_VAR + CASE(ZEND_JMP_SET_VAR); +#endif +#ifdef ZEND_DISCARD_EXCEPTION + CASE(ZEND_DISCARD_EXCEPTION); +#endif +#ifdef ZEND_YIELD + CASE(ZEND_YIELD); +#endif +#ifdef ZEND_GENERATOR_RETURN + CASE(ZEND_GENERATOR_RETURN); +#endif +#ifdef ZEND_FAST_CALL + CASE(ZEND_FAST_CALL); +#endif +#ifdef ZEND_FAST_RET + CASE(ZEND_FAST_RET); +#endif +#ifdef ZEND_RECV_VARIADIC + CASE(ZEND_RECV_VARIADIC); +#endif + CASE(ZEND_OP_DATA); + default: + return "UNKNOWN"; + } +#else const char *ret = zend_get_opcode_name(opcode); return ret?ret:"UNKNOWN"; +#endif } /* }}} */ From 86a77317630255a254888de4437a8b060efdb863 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sat, 12 Apr 2014 22:08:02 +0200 Subject: [PATCH 097/137] Fixed frame number order --- phpdbg_frame.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index de02addc1b9..a235fe8cb04 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -167,7 +167,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zval **tmp; zval **file, **line; HashPosition position; - int i = 1, limit = num; + int i = 0, limit = num; int user_defined; if (limit < 0) { @@ -186,7 +186,7 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { - phpdbg_write("frame #0: {main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + phpdbg_write("frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } From 3db29ee43960a4e164244a55b0e2a4b23a112e49 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 13 Apr 2014 00:27:46 +0200 Subject: [PATCH 098/137] Added support for command line arg passing "phpdbg -- arg" in shell "run arg" in phpdbg prompt --- phpdbg.c | 16 +++++++++++++++- phpdbg_help.c | 10 +++++++--- phpdbg_prompt.c | 26 ++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 7676687e712..ba12d94515d 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1139,8 +1139,16 @@ phpdbg_main: phpdbg->ini_entries = ini_entries; if (phpdbg->startup(phpdbg) == SUCCESS) { - php_request_startup(TSRMLS_C); + int i; + SG(request_info).argc = argc - php_optind + 1; + SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *)); + for (i = SG(request_info).argc; --i;) { + SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); + } + SG(request_info).argv[php_optind - 1] = exec?exec:""; + php_request_startup(TSRMLS_C); + /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifdef ZEND_SIGNALS @@ -1289,6 +1297,12 @@ phpdbg_out: } #endif + /* free argv */ + for (i = SG(request_info).argc; --i;) { + efree(SG(request_info).argv[i]); + } + efree(SG(request_info).argv); + #ifndef ZTS /* force cleanup of auto and core globals */ zend_hash_clean(CG(auto_globals)); diff --git a/phpdbg_help.c b/phpdbg_help.c index 3aa82848e00..dd8e5305226 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -379,7 +379,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **-S** **-S**cli Override SAPI name, careful!" CR " **-l** **-l**4000 Setup remote console ports" CR " **-a** **-a**192.168.0.3 Setup remote console bind address" CR -" **-V** Print version number" CR CR +" **-V** Print version number" CR +" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv " +"argument after it" CR CR "**Remote Console Mode**" CR CR @@ -838,11 +840,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { {"run", "Enter the vm, startinging execution. Execution will then continue until the next breakpoint " -"or completion of the script" +"or completion of the script. Add parameters you want to use as $argv" "**Examples**" CR CR " $P run" CR " $P r" CR -" Will cause execution of the context, if it is set." CR CR +" Will cause execution of the context, if it is set" CR CR +" $P r test" CR +" Will execute with $argv[1] == \"test\"" CR CR "Note that the execution context must be set. If not previously compiled, then the script will " "be compiled before execution." CR CR diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index e53a5e68b19..c088535eb42 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -289,6 +289,9 @@ PHPDBG_COMMAND(exec) /* {{{ */ PHPDBG_G(exec) = res; PHPDBG_G(exec_len) = res_len; + *SG(request_info).argv = PHPDBG_G(exec); + php_hash_environment(TSRMLS_C); + phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); } else { phpdbg_notice("Execution context not changed"); @@ -579,6 +582,29 @@ PHPDBG_COMMAND(run) /* {{{ */ /* reset hit counters */ phpdbg_reset_breakpoints(TSRMLS_C); + if (param->type != EMPTY_PARAM) { + char **argv = emalloc(5 * sizeof(char *)); + int argc = 0; + int i; + char *argv_str = strtok(input->string, " "); + while (argv_str) { + if (argc >= 4 && argc == (argc & -argc)) { + argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *)); + } + argv[++argc] = argv_str; + argv_str = strtok(0, " "); + argv[argc] = estrdup(argv[argc]); + } + argv[0] = SG(request_info).argv[0]; + for (i = SG(request_info).argc; --i;) { + efree(SG(request_info).argv[i]); + } + efree(SG(request_info).argv); + SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *)); + SG(request_info).argc = argc; + php_hash_environment(TSRMLS_C); + } + zend_try { php_output_activate(TSRMLS_C); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; From 2fde2ada50a00512490511349389d08ede9822f8 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 08:06:21 +0100 Subject: [PATCH 099/137] fix addr parameters --- dev/phpdbg_lexer.l | 4 ++-- phpdbg_lexer.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/phpdbg_lexer.l b/dev/phpdbg_lexer.l index fc63930e7e4..577155c1c01 100644 --- a/dev/phpdbg_lexer.l +++ b/dev/phpdbg_lexer.l @@ -92,8 +92,8 @@ INPUT [^\n]+ } {ADDR} { phpdbg_init_param(yylval, ADDR_PARAM); - yylval->addr = strtoul(yytext, NULL, 10); - return T_ADDR; + yylval->addr = strtoul(yytext, 0, 16); + return T_ADDR; } {OPCODE} { phpdbg_init_param(yylval, OP_PARAM); diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 7e29e1d661f..14bc525b0b7 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -943,8 +943,8 @@ YY_RULE_SETUP #line 93 "sapi/phpdbg/dev/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); - yylval->addr = strtoul(yytext, NULL, 10); - return T_ADDR; + yylval->addr = strtoul(yytext, 0, 16); + return T_ADDR; } YY_BREAK case 12: From 65984df220c494e431fa148f437115ca02cb7d39 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 08:09:53 +0100 Subject: [PATCH 100/137] merge master --- phpdbg_prompt.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 3010c088a55..373260c1d17 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -356,7 +356,6 @@ PHPDBG_COMMAND(exec) /* {{{ */ if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { -<<<<<<< HEAD if (PHPDBG_G(exec)) { phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec)); efree(PHPDBG_G(exec)); @@ -367,21 +366,13 @@ PHPDBG_COMMAND(exec) /* {{{ */ if (PHPDBG_G(ops)) { phpdbg_notice("Destroying compiled opcodes"); phpdbg_clean(0 TSRMLS_CC); -======= - *SG(request_info).argv = PHPDBG_G(exec); - php_hash_environment(TSRMLS_C); - - phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); - } else { - phpdbg_notice("Execution context not changed"); - } - } else { - phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str); ->>>>>>> 3db29ee43960a4e164244a55b0e2a4b23a112e49 } PHPDBG_G(exec) = res; PHPDBG_G(exec_len) = res_len; + + *SG(request_info).argv = PHPDBG_G(exec); + php_hash_environment(TSRMLS_C); phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); } else { From 4387723ef779135dfdaf36f1a3f451ca4c564877 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 08:34:16 +0100 Subject: [PATCH 101/137] fix argc/argv --- phpdbg.c | 3 ++- phpdbg_prompt.c | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 37a938f5554..89030731515 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1120,12 +1120,13 @@ phpdbg_main: if (phpdbg->startup(phpdbg) == SUCCESS) { int i; + SG(request_info).argc = argc - php_optind + 1; SG(request_info).argv = emalloc(SG(request_info).argc * sizeof(char *)); for (i = SG(request_info).argc; --i;) { SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); } - SG(request_info).argv[php_optind - 1] = exec?exec:""; + SG(request_info).argv[i] = exec?exec:""; php_request_startup(TSRMLS_C); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 373260c1d17..85f22ca9b5c 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -191,7 +191,9 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ { struct stat sb; - + + printf("try %s\n", init_file); + if (init_file && VCWD_STAT(init_file, &sb) != -1) { FILE *fp = fopen(init_file, "r"); if (fp) { @@ -304,7 +306,7 @@ next_line: if (free_init) { free(init_file); } - } + } else printf("failed to open %s\n", init_file); } /* }}} */ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC) /* {{{ */ @@ -648,7 +650,8 @@ PHPDBG_COMMAND(run) /* {{{ */ char **argv = emalloc(5 * sizeof(char *)); int argc = 0; int i; - char *argv_str = strtok(input->string, " "); + char *argv_str = NULL; + printf("param->str: %s\n", param->str); while (argv_str) { if (argc >= 4 && argc == (argc & -argc)) { argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *)); From 8c23b038cd6c685edf833b4598f0dbb4a88034d2 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 08:43:19 +0100 Subject: [PATCH 102/137] fix moar --- phpdbg.c | 5 ++--- phpdbg_prompt.c | 29 +++++++++++++++-------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 89030731515..e5a7956d14d 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1126,7 +1126,7 @@ phpdbg_main: for (i = SG(request_info).argc; --i;) { SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); } - SG(request_info).argv[i] = exec?exec:""; + SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup(""); php_request_startup(TSRMLS_C); @@ -1172,8 +1172,7 @@ phpdbg_main: PHPDBG_G(io)[PHPDBG_STDERR] = stderr; if (exec) { /* set execution context */ - PHPDBG_G(exec) = phpdbg_resolve_path( - exec TSRMLS_CC); + PHPDBG_G(exec) = phpdbg_resolve_path(exec TSRMLS_CC); PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); free(exec); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 85f22ca9b5c..576314f14a3 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -46,7 +46,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(compile, "attempt compilation", 'c', NULL, 0), PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), - PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, 0), + PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'F', NULL, 0), @@ -124,32 +124,32 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ * break; case METHOD_PARAM: - spprintf(&buffered, 0, "%s::%s" - TSRMLS_CC, next->method.class, next->method.name); + spprintf(&buffered, 0, "%s::%s", + next->method.class, next->method.name); add_next_index_string(¶ms, buffered, 0); break; case NUMERIC_METHOD_PARAM: - spprintf(&buffered, 0, "%s::%s#%ld" - TSRMLS_CC, next->method.class, next->method.name, next->num); + spprintf(&buffered, 0, "%s::%s#%ld", + next->method.class, next->method.name, next->num); add_next_index_string(¶ms, buffered, 0); break; case NUMERIC_FUNCTION_PARAM: - spprintf(&buffered, 0, "%s#%ld" - TSRMLS_CC, next->str, next->num); + spprintf(&buffered, 0, "%s#%ld", + next->str, next->num); add_next_index_string(¶ms, buffered, 0); break; case FILE_PARAM: - spprintf(&buffered, 0, "%s:%ld" - TSRMLS_CC, next->file.name, next->file.line); + spprintf(&buffered, 0, "%s:%ld", + next->file.name, next->file.line); add_next_index_string(¶ms, buffered, 0); break; case NUMERIC_FILE_PARAM: - spprintf(&buffered, 0, "%s:#%ld" - TSRMLS_CC, next->file.name, next->file.line); + spprintf(&buffered, 0, "%s:#%ld", + next->file.name, next->file.line); add_next_index_string(¶ms, buffered, 0); break; @@ -646,12 +646,12 @@ PHPDBG_COMMAND(run) /* {{{ */ /* reset hit counters */ phpdbg_reset_breakpoints(TSRMLS_C); - if (param->type != EMPTY_PARAM) { + if (param && param->type != EMPTY_PARAM) { char **argv = emalloc(5 * sizeof(char *)); int argc = 0; int i; - char *argv_str = NULL; - printf("param->str: %s\n", param->str); + char *argv_str = strtok(param->str, " "); + while (argv_str) { if (argc >= 4 && argc == (argc & -argc)) { argv = erealloc(argv, (argc * 2 + 1) * sizeof(char *)); @@ -667,6 +667,7 @@ PHPDBG_COMMAND(run) /* {{{ */ efree(SG(request_info).argv); SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *)); SG(request_info).argc = argc; + php_hash_environment(TSRMLS_C); } From 0dc9be6f1e807f4556283d2c90fa3bab50c45334 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 08:48:59 +0100 Subject: [PATCH 103/137] cleanup --- phpdbg_prompt.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 576314f14a3..0bd6701f36a 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -192,8 +192,6 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ { struct stat sb; - printf("try %s\n", init_file); - if (init_file && VCWD_STAT(init_file, &sb) != -1) { FILE *fp = fopen(init_file, "r"); if (fp) { @@ -306,7 +304,7 @@ next_line: if (free_init) { free(init_file); } - } else printf("failed to open %s\n", init_file); + } } /* }}} */ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC) /* {{{ */ From b8a4a4c700af6373c87b955e64808f1b927f7ccc Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 09:07:15 +0100 Subject: [PATCH 104/137] squish warnings --- dev/phpdbg_parser.y | 2 +- phpdbg_list.c | 13 +++++-------- phpdbg_parser.c | 2 +- phpdbg_set.c | 2 ++ 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/dev/phpdbg_parser.y b/dev/phpdbg_parser.y index 9d31a5d3e7a..58306e07f91 100644 --- a/dev/phpdbg_parser.y +++ b/dev/phpdbg_parser.y @@ -26,7 +26,6 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { phpdbg_error("Parse Error: %s", msg); { const phpdbg_param_t *top = stack; - zend_ulong position = 0L; while (top) { phpdbg_param_debug( @@ -34,6 +33,7 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { top = top->next; } } + return 0; } %} diff --git a/phpdbg_list.c b/phpdbg_list.c index 96c47287071..037c6c38b2a 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -54,7 +54,6 @@ PHPDBG_LIST(lines) /* {{{ */ switch (param->type) { case NUMERIC_PARAM: - printf("list lines: %d\n", param->num); phpdbg_list_file(phpdbg_current_file(TSRMLS_C), (param->num < 0 ? 1 - param->num : param->num), (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), @@ -128,10 +127,8 @@ PHPDBG_LIST(class) /* {{{ */ void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */ { struct stat st; - char *opened = NULL, - *mem = NULL; + char *opened = NULL; char buffer[8096] = {0,}; - size_t buflen = 0L; long line = 0; php_stream *stream = NULL; @@ -148,18 +145,18 @@ void phpdbg_list_file(const char *filename, long count, long offset, int highlig return; } - while ((buflen = php_stream_gets(stream, buffer, sizeof(buffer))) > 0L) { + while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) { ++line; if (!offset || offset <= line) { /* Without offset, or offset reached */ if (!highlight) { - phpdbg_write("%05u: %s", line, buffer); + phpdbg_write("%05ld: %s", line, buffer); } else { if (highlight != line) { - phpdbg_write(" %05u: %s", line, buffer); + phpdbg_write(" %05ld: %s", line, buffer); } else { - phpdbg_write(">%05u: %s", line, buffer); + phpdbg_write(">%05ld: %s", line, buffer); } } } diff --git a/phpdbg_parser.c b/phpdbg_parser.c index 6ea96d84d51..eabe78e7931 100644 --- a/phpdbg_parser.c +++ b/phpdbg_parser.c @@ -91,7 +91,6 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { phpdbg_error("Parse Error: %s", msg); { const phpdbg_param_t *top = stack; - zend_ulong position = 0L; while (top) { phpdbg_param_debug( @@ -99,6 +98,7 @@ int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { top = top->next; } } + return 0; } /* Line 371 of yacc.c */ diff --git a/phpdbg_set.c b/phpdbg_set.c index fa462e2f182..e8027a8930b 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -203,6 +203,8 @@ PHPDBG_SET(quiet) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IS_QUIET; } else PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; } break; + + phpdbg_default_switch_case(); } return SUCCESS; From 1b2f12159b5876f45746bc7335c8effcdf621e4a Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 11:17:04 +0100 Subject: [PATCH 105/137] fix command structure --- phpdbg_watch.h | 1 + 1 file changed, 1 insertion(+) diff --git a/phpdbg_watch.h b/phpdbg_watch.h index b5aba3c23cd..7c3a160034c 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -45,6 +45,7 @@ static const phpdbg_command_t phpdbg_watch_commands[] = { PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s"), PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s"), PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s"), + PHPDBG_END_COMMAND }; /* Watchpoint functions/typedefs */ From c2c4a5bd250909f2635f6d352d5900b5132a0281 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 11:32:35 +0100 Subject: [PATCH 106/137] fix build --- phpdbg_bp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 15b00c1d01a..a18316a2285 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -1000,7 +1000,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut zend_try { PHPDBG_G(flags) |= PHPDBG_IN_COND_BP; zend_execute(EG(active_op_array) TSRMLS_CC); -#if PHP_VERSION_ID >= 50600 +#if PHP_VERSION_ID >= 50700 if (zend_is_true(retval TSRMLS_CC)) { #else if (zend_is_true(retval)) { From faa7e3264e4f1d91678baf4ef1287e655f81c61d Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 11:42:47 +0100 Subject: [PATCH 107/137] fix compat with lexer stuff --- phpdbg_prompt.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 93bc638089b..bc2e667e6b9 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -66,7 +66,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(export, "export breaks to a .phpdbginit script", '>', NULL, "s"), PHPDBG_COMMAND_D(sh, "shell a command", 0, NULL, "i"), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), - PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "ss"), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', phpdbg_watch_commands, "|ss"), PHPDBG_END_COMMAND }; /* }}} */ @@ -1002,15 +1002,13 @@ PHPDBG_COMMAND(list) /* {{{ */ PHPDBG_COMMAND(watch) /* {{{ */ { - switch (param->type) { + if (!param || param->type == EMPTY_PARAM) { + phpdbg_list_watchpoints(TSRMLS_C); + } else switch (param->type) { case STR_PARAM: phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC); break; - case EMPTY_PARAM: - phpdbg_list_watchpoints(TSRMLS_C); - break; - phpdbg_default_switch_case(); } From 286dd4dc714e18d28dca61efb4143cf214f09650 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 13 Apr 2014 13:33:07 +0200 Subject: [PATCH 108/137] Remove some dead code... --- phpdbg_win.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/phpdbg_win.c b/phpdbg_win.c index 55d4b0f94d1..b0cbdf267a1 100644 --- a/phpdbg_win.c +++ b/phpdbg_win.c @@ -21,26 +21,22 @@ #include "zend.h" #include "phpdbg.h" -phpdbg_btree phpdbg_memory_tree; - int mprotect(void *addr, size_t size, int protection) { int var; return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var); } -size_t virtual_size(void *ptr) { - return (size_t)phpdbg_btree_find(&phpdbg_memory_tree, (zend_ulong)ptr)->ptr; -} - int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) { EXCEPTION_RECORD *xr = xp->ExceptionRecord; CONTEXT *xc = xp->ContextRecord; + if(xr->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) { TSRMLS_FETCH(); - //printf("Watchpoint hit at: %p\n", xr->ExceptionInformation[1]); + if (phpdbg_watchpoint_segfault_handler((void *)xr->ExceptionInformation[1] TSRMLS_CC) == SUCCESS) { return EXCEPTION_CONTINUE_EXECUTION; } } + return EXCEPTION_CONTINUE_SEARCH; } From ce7097fb607a43396aa2785cae07de4d6a196f74 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 14:43:34 +0100 Subject: [PATCH 109/137] less strange! --- phpdbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg.c b/phpdbg.c index c1bb206eb8e..213906a977b 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1183,7 +1183,7 @@ phpdbg_main: sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); #endif - if (php_request_startup(TSRMLS_C) == SUCCESS) {; + if (php_request_startup(TSRMLS_C) == SUCCESS) { int i; SG(request_info).argc = argc - php_optind + 1; From eae91d9de78a44410c43c18bb42e83e09bd7c5ba Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 13 Apr 2014 17:34:27 +0200 Subject: [PATCH 110/137] Added help --- phpdbg_help.c | 34 ++++++++++++++++++++++++++++++++-- phpdbg_prompt.c | 4 +++- phpdbg_watch.c | 14 ++++++++++---- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 72038dc0fd7..757dc769b35 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -334,6 +334,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **finish** continue up to end of the current execution frame" CR " **leave** continue up to end of the current execution frame and halt after the calling instruction" CR " **break** set a breakpoint at the specified target" CR +" **watch"" set a watchpoint on $variable" CR " **ev** evaluate some code" CR " **clear** clear one or all breakpoints" CR " **clean** clean the execution environment" CR CR @@ -838,8 +839,8 @@ phpdbg_help_text_t phpdbg_help_text[] = { " Set the prompt to a bold >" CR CR " $P S c error red-bold" CR -" Use red bold for errors" CR -" " CR +" Use red bold for errors" CR CR + " $P S b 4 off" CR " Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR //*********** check oplog syntax @@ -903,6 +904,35 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note **until** will trigger a \"not executing\" error if not executing." +}, +{"watch", +"Sets watchpoints on variables as long as they are defined" CR +"Passing no parameter to **watch**, lists all actually active watchpoints" CR +"Subcommands of **watch**:" CR CR + +" **Type** **Alias** **Purpose**" CR +" **array** **a** Sets watchpoint on array/object to observe if an entry is added or removed" CR +" **recursive** **r** Watches variable recursively and automatically adds watchpoints if some entry is added to an array/object" CR +" **delete** **d** Removes watchpoint" CR CR + +"Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" + +"**Examples**" CR CR +" $P watch $array" CR +" Set watchpoint on $array" CR CR + +" $P watch" CR +" $array" CR CR + +" $P w r $obj" CR +" Set recursive watchpoint on $obj" CR CR + +" $P w d $obj" CR +" Removed watchpoint $obj" CR CR + +"Technical note: If using this feature with a debugger, you will get many segmentation faults, each time when a memory page containing a watched address is hit." CR +" You then you can continue, phpdbg will remove the write protection, so that the program can continue." CR +" If phpdbg could not handle that segfault, the same segfault is triggered again and this time phpdbg will abort." }, {NULL, NULL /* end of table marker */} }; /* }}} */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index bc2e667e6b9..9a9f45b8fac 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1006,7 +1006,9 @@ PHPDBG_COMMAND(watch) /* {{{ */ phpdbg_list_watchpoints(TSRMLS_C); } else switch (param->type) { case STR_PARAM: - phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC); + if (phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set watchpoint on %.*s", (int)param->len, param->str); + } break; phpdbg_default_switch_case(); diff --git a/phpdbg_watch.c b/phpdbg_watch.c index a1bb742cd62..ef5881ff945 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -392,6 +392,8 @@ PHPDBG_WATCH(delete) /* {{{ */ case STR_PARAM: if (phpdbg_delete_var_watchpoint(param->str, param->len TSRMLS_CC) == FAILURE) { phpdbg_error("Nothing was deleted, no corresponding watchpoint found"); + } else { + phpdbg_notice("Removed watchpoint %.*s", (int)param->len, param->str); } break; @@ -409,7 +411,9 @@ PHPDBG_WATCH(recursive) /* {{{ */ switch (param->type) { case STR_PARAM: - phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_recursive_watchpoint TSRMLS_CC); + if (phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set recursive watchpoint on %.*s", (int)param->len, param->str); + } break; phpdbg_default_switch_case(); @@ -426,7 +430,9 @@ PHPDBG_WATCH(array) /* {{{ */ switch (param->type) { case STR_PARAM: - phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_array_watchpoint TSRMLS_CC); + if (phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) { + phpdbg_notice("Set array watchpoint on %.*s", (int)param->len, param->str); + } break; phpdbg_default_switch_case(); @@ -460,7 +466,7 @@ void phpdbg_watch_HashTable_dtor(zval **zv) { int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { - return SUCCESS; + return FAILURE; } return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_create_watchpoint TSRMLS_CC); @@ -468,7 +474,7 @@ int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { if (phpdbg_rebuild_symtable(TSRMLS_C) == FAILURE) { - return SUCCESS; + return FAILURE; } return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_delete_watchpoint TSRMLS_CC); From f53e438933cacad70d667e0ef90e2ce0e79f9b16 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 13 Apr 2014 17:48:35 +0200 Subject: [PATCH 111/137] Added information about $var parameter in watchpoints --- phpdbg_help.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 757dc769b35..b75f7381e3e 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -334,7 +334,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **finish** continue up to end of the current execution frame" CR " **leave** continue up to end of the current execution frame and halt after the calling instruction" CR " **break** set a breakpoint at the specified target" CR -" **watch"" set a watchpoint on $variable" CR +" **watch** set a watchpoint on $variable" CR " **ev** evaluate some code" CR " **clear** clear one or all breakpoints" CR " **clean** clean the execution environment" CR CR @@ -907,7 +907,15 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, {"watch", "Sets watchpoints on variables as long as they are defined" CR -"Passing no parameter to **watch**, lists all actually active watchpoints" CR +"Passing no parameter to **watch**, lists all actually active watchpoints" CR CR + +"**Format for $variable**" CR CR +" **$var** Variable $var" CR +" **$var[]** All array elements of $var" CR +" **$var->** All properties of $var" CR +" **$var->a** Property $var->a" CR +" **$var[b]** Array element with key b in array $var" CR CR + "Subcommands of **watch**:" CR CR " **Type** **Alias** **Purpose**" CR @@ -924,11 +932,11 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P watch" CR " $array" CR CR -" $P w r $obj" CR -" Set recursive watchpoint on $obj" CR CR +" $P w r $obj->" CR +" Set recursive watchpoint on $obj->" CR CR -" $P w d $obj" CR -" Removed watchpoint $obj" CR CR +" $P w d $obj->a" CR +" Removed watchpoint $obj->a" CR CR "Technical note: If using this feature with a debugger, you will get many segmentation faults, each time when a memory page containing a watched address is hit." CR " You then you can continue, phpdbg will remove the write protection, so that the program can continue." CR From 2f54e68ade8c74fb2b1208518a368c377a55df27 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 13 Apr 2014 17:55:18 +0200 Subject: [PATCH 112/137] CR CR etc. in help --- phpdbg_help.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index b75f7381e3e..da86823a6d4 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -923,13 +923,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **recursive** **r** Watches variable recursively and automatically adds watchpoints if some entry is added to an array/object" CR " **delete** **d** Removes watchpoint" CR CR -"Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" +"Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" CR CR "**Examples**" CR CR " $P watch $array" CR " Set watchpoint on $array" CR CR -" $P watch" CR +" $P watch (assuming we just have set a watchpoint on $array)" CR " $array" CR CR " $P w r $obj->" CR From 774a879e6522501f357e8a68278dc321ab118079 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 13 Apr 2014 16:58:45 +0100 Subject: [PATCH 113/137] tidy help --- phpdbg_help.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index da86823a6d4..365b75c8c91 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -926,17 +926,20 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note when **recursive** watchpoints are removed, watchpoints on all the children are removed too" CR CR "**Examples**" CR CR +" $P watch" CR +" List currently active watchpoints" CR CR + " $P watch $array" CR +" $P w $array" CR " Set watchpoint on $array" CR CR -" $P watch (assuming we just have set a watchpoint on $array)" CR -" $array" CR CR - +" $P watch recursive $obj->" CR " $P w r $obj->" CR " Set recursive watchpoint on $obj->" CR CR +" $P watch delete $obj->a" CR " $P w d $obj->a" CR -" Removed watchpoint $obj->a" CR CR +" Remove watchpoint $obj->a" CR CR "Technical note: If using this feature with a debugger, you will get many segmentation faults, each time when a memory page containing a watched address is hit." CR " You then you can continue, phpdbg will remove the write protection, so that the program can continue." CR From fdd9bc20507f04bdcdeb963a26a9334409885c5c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 14 Apr 2014 10:46:52 +0200 Subject: [PATCH 114/137] Clean up information on watchpoint breaks --- phpdbg_watch.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index ef5881ff945..d7da10e7aa6 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -616,14 +616,21 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { switch (watch->type) { case WATCH_ON_ZVAL: { int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1); + int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value)); + int show_ref = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc || ((zval *)oldPtr)->is_ref__gc != watch->addr.zv->is_ref__gc; - phpdbg_write("Old value: "); - if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { - phpdbg_write("Value inaccessible, HashTable already destroyed"); - } else { - zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + if (removed || show_value) { + phpdbg_write("Old value: "); + if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) { + phpdbg_writeln("Value inaccessible, HashTable already destroyed"); + } else { + zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC); + phpdbg_writeln(""); + } + } + if (removed || show_ref) { + phpdbg_writeln("Old refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); } - phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); /* check if zval was removed */ if (removed) { @@ -639,9 +646,14 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { break; } - phpdbg_write("New value: "); - zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); - phpdbg_writeln("\nNew refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + if (show_value) { + phpdbg_write("New value: "); + zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); + phpdbg_writeln(""); + } + if (show_ref) { + phpdbg_writeln("New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); + } if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *)oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *)oldPtr))) { /* add new watchpoints if necessary */ From 8c22352e885986096f0293bddf57feddbdeac335 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 14 Apr 2014 15:45:15 +0200 Subject: [PATCH 115/137] Added $this and superglobals support for watchpoints --- phpdbg.c | 2 ++ phpdbg_watch.c | 43 ++++++++++++++++++++++++++++++++----------- phpdbg_watch.h | 4 ++-- test.php | 8 +++++++- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 213906a977b..7a90b8d86b5 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1192,6 +1192,8 @@ phpdbg_main: SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); } SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup(""); + + php_hash_environment(TSRMLS_C); } /* do not install sigint handlers for remote consoles */ diff --git a/phpdbg_watch.c b/phpdbg_watch.c index d7da10e7aa6..b0edcefb237 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -138,6 +138,13 @@ static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) return SUCCESS; } +static char *phpdbg_get_property_key(char *key) { + if (*key != 0) { + return key; + } + return strchr(key + 1, 0) + 1; +} + static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) { HashTable *ht; @@ -183,7 +190,7 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_ } new_watch->str = NULL; - new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%.*s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", (int)new_watch->name_in_parent_len, new_watch->name_in_parent, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); + new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int)watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY?"]":""); phpdbg_create_zval_watchpoint(*zv, new_watch); phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC); @@ -229,7 +236,7 @@ static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_b zend_hash_get_current_key_zval_ex(ht, &key, &position); str = NULL; if (Z_TYPE(key) == IS_STRING) { - str_len = asprintf(&str, "%.*s%s%.*s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_STRLEN(key), Z_STRVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); + str_len = asprintf(&str, "%.*s%s%s%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); } else { str_len = asprintf(&str, "%.*s%s%li%s", (int)watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"[":"->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY?"]":""); } @@ -280,7 +287,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) { return ret; } -static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { +static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *parent, size_t i, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC), zend_bool silent TSRMLS_DC) { int ret = FAILURE; zend_bool new_index = 1; char *last_index; @@ -332,7 +339,7 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par zend_hash_get_current_key_zval_ex(parent, key, &position); convert_to_string(key); watch->str = malloc(i + Z_STRLEN_P(key) + 2); - watch->str_len = sprintf(watch->str, "%.*s%.*s%s", (int)i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":""); + watch->str_len = sprintf(watch->str, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":""); efree(key); watch->name_in_parent = zend_strndup(last_index, index_len); watch->name_in_parent_len = index_len; @@ -341,9 +348,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par ret = callback(watch TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE; } else if (Z_TYPE_PP(zv) == IS_OBJECT) { - phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback TSRMLS_CC); + phpdbg_watchpoint_parse_input(input, len, Z_OBJPROP_PP(zv), i, callback, silent TSRMLS_CC); } else if (Z_TYPE_PP(zv) == IS_ARRAY) { - phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback TSRMLS_CC); + phpdbg_watchpoint_parse_input(input, len, Z_ARRVAL_PP(zv), i, callback, silent TSRMLS_CC); } else { /* Ignore silently */ } @@ -353,7 +360,9 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par char last_chr = last_index[index_len]; last_index[index_len] = 0; if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) { - phpdbg_error("%.*s is undefined", (int)i, input); + if (!silent) { + phpdbg_error("%.*s is undefined", (int)i, input); + } return FAILURE; } last_index[index_len] = last_chr; @@ -386,6 +395,18 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par return FAILURE; } +static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) { + if (EG(This) && len >= 5 && !memcmp("$this", input, 5)) { + zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL); + } + + if (zend_is_auto_global(input, len TSRMLS_CC)) { + phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC); + } + + return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, callback, 0 TSRMLS_CC); +} + PHPDBG_WATCH(delete) /* {{{ */ { switch (param->type) { @@ -411,7 +432,7 @@ PHPDBG_WATCH(recursive) /* {{{ */ switch (param->type) { case STR_PARAM: - if (phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) { + if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_recursive_watchpoint TSRMLS_CC) != FAILURE) { phpdbg_notice("Set recursive watchpoint on %.*s", (int)param->len, param->str); } break; @@ -430,7 +451,7 @@ PHPDBG_WATCH(array) /* {{{ */ switch (param->type) { case STR_PARAM: - if (phpdbg_watchpoint_parse_input(param->str, param->len, EG(active_symbol_table), 0, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) { + if (phpdbg_watchpoint_parse_symtables(param->str, param->len, phpdbg_create_array_watchpoint TSRMLS_CC) != FAILURE) { phpdbg_notice("Set array watchpoint on %.*s", (int)param->len, param->str); } break; @@ -469,7 +490,7 @@ int phpdbg_create_var_watchpoint(char *input, size_t len TSRMLS_DC) { return FAILURE; } - return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_create_watchpoint TSRMLS_CC); + return phpdbg_watchpoint_parse_symtables(input, len, phpdbg_create_watchpoint TSRMLS_CC); } int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { @@ -477,7 +498,7 @@ int phpdbg_delete_var_watchpoint(char *input, size_t len TSRMLS_DC) { return FAILURE; } - return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, phpdbg_delete_watchpoint TSRMLS_CC); + return phpdbg_watchpoint_parse_symtables(input, len, phpdbg_delete_watchpoint TSRMLS_CC); } #ifdef _WIN32 diff --git a/phpdbg_watch.h b/phpdbg_watch.h index 7c3a160034c..d00bcff77e5 100644 --- a/phpdbg_watch.h +++ b/phpdbg_watch.h @@ -56,8 +56,8 @@ typedef enum { } phpdbg_watchtype; -#define PHPDBG_WATCH_SIMPLE 0 -#define PHPDBG_WATCH_RECURSIVE 1 +#define PHPDBG_WATCH_SIMPLE 0x0 +#define PHPDBG_WATCH_RECURSIVE 0x1 typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t; diff --git a/test.php b/test.php index e28b8dab984..a18851ca4a7 100644 --- a/test.php +++ b/test.php @@ -70,7 +70,13 @@ array_walk($array, function (&$item) { $item -= 1; }); -$obj = (object)["a" => 2, "b" => 5, "c" => 7]; +class testClass { + public $a = 2; + protected $b = [1, 3]; + private $c = 7; +} + +$obj = new testClass; $test = $obj->a; From 2dad85ae61bbc2817798cb98680abfabd9e19d33 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 14 Apr 2014 16:26:27 +0200 Subject: [PATCH 116/137] Return SUCCESS and do not confuse use with errors --- phpdbg_watch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index b0edcefb237..41c5788a19c 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -400,8 +400,8 @@ static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*call zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL); } - if (zend_is_auto_global(input, len TSRMLS_CC)) { - phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC); + if (zend_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC) != FAILURE) { + return SUCCESS; } return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, callback, 0 TSRMLS_CC); From 9b05f5d1327aff7f828ba21e705f6a1da306059e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 14 Apr 2014 19:37:31 +0200 Subject: [PATCH 117/137] Made refcount info switchable by set refcount on/off. Default: off --- phpdbg.h | 2 ++ phpdbg_help.c | 17 +++++++++-------- phpdbg_set.c | 32 ++++++++++++++++++++++++++------ phpdbg_set.h | 1 + phpdbg_watch.c | 11 +++++++++-- test.php | 11 ++++++----- 6 files changed, 53 insertions(+), 21 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index 970a9022ade..42938d9e339 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -139,6 +139,8 @@ #define PHPDBG_IS_REMOTE (1<<26) #define PHPDBG_IS_DISCONNECTED (1<<27) +#define PHPDBG_SHOW_REFCOUNTS (1<<28) + #define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) #define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) #define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) diff --git a/phpdbg_help.c b/phpdbg_help.c index 365b75c8c91..250fb132d2b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -815,14 +815,15 @@ phpdbg_help_text_t phpdbg_help_text[] = { "The **set** command is used to configure how phpdbg looks and behaves. Specific set commands " "are as follows:" CR CR -" **Type** **Alias** **Purpose**" CR -" **prompt** **p** set the prompt" CR -" **color** **c** set color " CR -" **colors** **C** set colors " CR -" **oplog** **O** set oplog output" CR -" **break** **b** set break **id** " CR -" **breaks** **B** set breaks " CR -" **quiet** **q** set quiet " CR CR +" **Type** **Alias** **Purpose**" CR +" **prompt** **p** set the prompt" CR +" **color** **c** set color " CR +" **colors** **C** set colors " CR +" **oplog** **O** set oplog output" CR +" **break** **b** set break **id** " CR +" **breaks** **B** set breaks " CR +" **quiet** **q** set quiet " CR +" **refcount** **r** set refcount (refcount display upon hit watchpoint)" CR CR "Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, " "**cyan** and **black**. All colours except **none** can be followed by an optional " diff --git a/phpdbg_set.c b/phpdbg_set.c index e8027a8930b..aeb882657eb 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -34,12 +34,13 @@ const phpdbg_command_t phpdbg_set_commands[] = { PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt []", 'p', set_prompt, NULL, "|s"), #ifndef _WIN32 PHPDBG_SET_COMMAND_D(color, "usage: set color ", 'c', set_color, NULL, "ss"), - PHPDBG_SET_COMMAND_D(colors, "usage: set colors []", 'C', set_colors, NULL, "|b"), + PHPDBG_SET_COMMAND_D(colors, "usage: set colors []", 'C', set_colors, NULL, "|b"), #endif PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog []", 'O', set_oplog, NULL, "|s"), PHPDBG_SET_COMMAND_D(break, "usage: set break id []", 'b', set_break, NULL, "l|b"), PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks []", 'B', set_breaks, NULL, "|b"), PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet []", 'q', set_quiet, NULL, "|b"), + PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount []", 'r', set_refcount, NULL, "|b"), PHPDBG_END_COMMAND }; @@ -195,18 +196,37 @@ PHPDBG_SET(oplog) /* {{{ */ PHPDBG_SET(quiet) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Quietness %s", - PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); - } else switch (param->type) { + phpdbg_writeln("Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { PHPDBG_G(flags) |= PHPDBG_IS_QUIET; - } else PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } else { + PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET; + } } break; - + phpdbg_default_switch_case(); } return SUCCESS; } /* }}} */ +PHPDBG_SET(refcount) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Showing refcounts on watchpoints %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + } else switch (param->type) { + case NUMERIC_PARAM: { + if (param->num) { + PHPDBG_G(flags) |= PHPDBG_SHOW_REFCOUNTS; + } else { + PHPDBG_G(flags) &= ~PHPDBG_SHOW_REFCOUNTS; + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ diff --git a/phpdbg_set.h b/phpdbg_set.h index 4d90aac5b2d..67bf4cd7def 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -34,6 +34,7 @@ PHPDBG_SET(oplog); PHPDBG_SET(break); PHPDBG_SET(breaks); PHPDBG_SET(quiet); +PHPDBG_SET(refcount); extern const phpdbg_command_t phpdbg_set_commands[]; diff --git a/phpdbg_watch.c b/phpdbg_watch.c index 41c5788a19c..fe161ab7a8e 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -631,9 +631,16 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { /* Show to the user what changed and delete watchpoint upon removal */ if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) { - PHPDBG_G(watchpoint_hit) = 1; + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE +#if ZEND_DEBUG + && !watch->addr.ht->inconsistent +#endif + && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht))) { + PHPDBG_G(watchpoint_hit) = 1; + + phpdbg_notice("Breaking on watchpoint %s", watch->str); + } - phpdbg_notice("Breaking on watchpoint %s", watch->str); switch (watch->type) { case WATCH_ON_ZVAL: { int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1); diff --git a/test.php b/test.php index a18851ca4a7..d93c81a89a4 100644 --- a/test.php +++ b/test.php @@ -6,11 +6,12 @@ if (isset($include)) { $stdout = fopen("php://stdout", "w+"); class phpdbg { - public function isGreat($greeting = null) { - printf( - "%s: %s\n", __METHOD__, $greeting); - return $this; - } + private $sprintf = "%s: %s\n"; + + public function isGreat($greeting = null) { + printf($this->sprintf, __METHOD__, $greeting); + return $this; + } } function mine() { From 0e8637441c10c1a028d9c4619d32bb8ce9cb3ce4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 15 Apr 2014 15:52:46 +0000 Subject: [PATCH 118/137] Fixed segfault when input == NULL --- phpdbg_cmd.c | 9 ++++++--- phpdbg_prompt.c | 13 ++++++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index cc597f13eec..c6818fea3f7 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -516,21 +516,24 @@ PHPDBG_API void phpdbg_stack_free(phpdbg_param_t *stack) { /* {{{ */ PHPDBG_API void phpdbg_stack_push(phpdbg_param_t *stack, phpdbg_param_t *param) { phpdbg_param_t *next = calloc(1, sizeof(phpdbg_param_t)); - + if (!next) return; - + *(next) = *(param); + next->next = NULL; + if (stack->top == NULL) { stack->top = next; + next->top = NULL; stack->next = next; } else { stack->top->next = next; next->top = stack->top; stack->top = next; } - + stack->len++; } /* }}} */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 9a9f45b8fac..86fc4d718e5 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1023,18 +1023,18 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ char *why = NULL; char *input = NULL; phpdbg_param_t stack; - + PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; input = phpdbg_read_input(NULL TSRMLS_CC); - + if (input) { do { yyscan_t scanner; YY_BUFFER_STATE state; phpdbg_init_param(&stack, STACK_PARAM); - + if (yylex_init(&scanner)) { phpdbg_error( "could not initialize scanner"); @@ -1042,7 +1042,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } state = yy_scan_string(input, scanner); - + if (yyparse(&stack, scanner) <= 0) { switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: @@ -1053,7 +1053,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } } } - + if (why) { free(why); why = NULL; @@ -1099,14 +1099,13 @@ last: out: if (input) { + phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); } if (why) { free(why); } - - phpdbg_stack_free(&stack); if (EG(in_execution)) { phpdbg_restore_frame(TSRMLS_C); From a981e3a1d2f3de60f239db4cbca4ace0e53a9193 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 15 Apr 2014 19:20:01 +0200 Subject: [PATCH 119/137] Fixed refcount removing if specified --- phpdbg_watch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_watch.c b/phpdbg_watch.c index fe161ab7a8e..a6bf6289bf5 100644 --- a/phpdbg_watch.c +++ b/phpdbg_watch.c @@ -656,7 +656,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { phpdbg_writeln(""); } } - if (removed || show_ref) { + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) { phpdbg_writeln("Old refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc); } @@ -679,7 +679,7 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) { zend_print_flat_zval_r(watch->addr.zv TSRMLS_CC); phpdbg_writeln(""); } - if (show_ref) { + if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) { phpdbg_writeln("New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc); } From 7ab1c07a513f520fff0e4dbb39b924d9000ba5d4 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 16 Apr 2014 11:40:29 +0200 Subject: [PATCH 120/137] Fixed bug: ev output was buffered instead of directly displayed --- phpdbg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpdbg.c b/phpdbg.c index 7a90b8d86b5..2648d60ff2b 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1195,6 +1195,10 @@ phpdbg_main: php_hash_environment(TSRMLS_C); } + + /* make sure to turn off buffer for ev command */ + php_output_activate(TSRMLS_C); + php_output_deactivate(TSRMLS_C); /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ From b1a22ae6dc2b9d530b385661d56d62ae584a1016 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 16 Apr 2014 13:56:26 +0200 Subject: [PATCH 121/137] Updated version number to 0.4.0 Made run accept any input and lexer re2c compatible --- .gitignore | 4 +- Makefile.frag | 9 + phpdbg.h | 2 +- phpdbg_cmd.c | 3 + phpdbg_cmd.h | 3 +- phpdbg_lexer.c | 308 ++-- phpdbg_lexer.h | 16 +- dev/phpdbg_lexer.l => phpdbg_lexer.l | 42 +- phpdbg_parser.c | 1843 ------------------------ phpdbg_parser.h | 105 -- dev/phpdbg_parser.y => phpdbg_parser.y | 6 + 11 files changed, 194 insertions(+), 2147 deletions(-) rename dev/phpdbg_lexer.l => phpdbg_lexer.l (75%) delete mode 100644 phpdbg_parser.c delete mode 100644 phpdbg_parser.h rename dev/phpdbg_parser.y => phpdbg_parser.y (97%) diff --git a/.gitignore b/.gitignore index 297efcbc420..af445861acd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .libs/ -./phpdbg +phpdbg *.lo *.o build +phpdbg_parser.c +phpdbg_parser.h diff --git a/Makefile.frag b/Makefile.frag index 77f5788894a..45768de2eff 100644 --- a/Makefile.frag +++ b/Makefile.frag @@ -8,6 +8,15 @@ $(BUILD_SHARED): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(BUILD_BINARY): $(PHP_GLOBAL_OBJS) $(PHP_BINARY_OBJS) $(PHP_PHPDBG_OBJS) $(BUILD_PHPDBG) +$(builddir)/sapi/phpdbg/phpdbg_lexer.lo: $(srcdir)/sapi/phpdbg/phpdbg_parser.h + +$(srcdir)/sapi/phpdbg/phpdbg_lexer.c: $(srcdir)/sapi/phpdbg/phpdbg_lexer.l + @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date -cbdFo sapi/phpdbg/phpdbg_lexer.c sapi/phpdbg/phpdbg_lexer.l) + +$(srcdir)/sapi/phpdbg/phpdbg_parser.h: $(srcdir)/sapi/phpdbg/phpdbg_parser.c +$(srcdir)/sapi/phpdbg/phpdbg_parser.c: $(srcdir)/sapi/phpdbg/phpdbg_parser.y + @$(YACC) -p phpdbg_ -v -d $(srcdir)/sapi/phpdbg/phpdbg_parser.y -o $@ + install-phpdbg: $(BUILD_BINARY) @echo "Installing phpdbg binary: $(INSTALL_ROOT)$(bindir)/" @$(mkinstalldirs) $(INSTALL_ROOT)$(bindir) diff --git a/phpdbg.h b/phpdbg.h index 42938d9e339..43f26ca3236 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -156,7 +156,7 @@ #define PHPDBG_AUTHORS "Felipe Pena, Joe Watkins and Bob Weinand" /* Ordered by last name */ #define PHPDBG_URL "http://phpdbg.com" #define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues" -#define PHPDBG_VERSION "0.3.2" +#define PHPDBG_VERSION "0.4.0" #define PHPDBG_INIT_FILENAME ".phpdbginit" /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index c6818fea3f7..ce66ba39eca 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -762,6 +762,9 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, char **why TSRMLS_DC) switch (top->type) { case EVAL_PARAM: return PHPDBG_COMMAND_HANDLER(ev)(top TSRMLS_CC); + + case RUN_PARAM: + return PHPDBG_COMMAND_HANDLER(run)(top TSRMLS_CC); case SHELL_PARAM: return PHPDBG_COMMAND_HANDLER(sh)(top TSRMLS_CC); diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index af93ba54d4b..571d065f59d 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -45,7 +45,8 @@ typedef enum { SHELL_PARAM, COND_PARAM, OP_PARAM, - ORIG_PARAM + ORIG_PARAM, + RUN_PARAM } phpdbg_param_type; typedef struct _phpdbg_param phpdbg_param_t; diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index 14bc525b0b7..fc8d846b73b 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -9,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 +#define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -47,6 +47,7 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -54,6 +55,7 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -84,8 +86,6 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! C99 */ - #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -326,7 +326,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(yyscanner) 1 +#define yywrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -345,13 +345,13 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 16 -#define YY_END_OF_BUFFER 17 +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -359,15 +359,16 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[70] = +static yyconst flex_int16_t yy_accept[73] = { 0, - 0, 0, 0, 0, 17, 13, 15, 2, 10, 10, - 4, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 14, 14, 13, 0, 15, 10, 13, 3, 13, - 13, 5, 13, 7, 9, 13, 8, 6, 13, 13, - 13, 14, 14, 0, 11, 13, 13, 13, 9, 13, - 8, 13, 1, 13, 13, 13, 8, 13, 13, 13, - 9, 13, 13, 13, 12, 13, 8, 9, 0 + 0, 0, 0, 0, 18, 14, 16, 2, 11, 11, + 4, 14, 14, 14, 14, 14, 14, 14, 8, 14, + 14, 14, 14, 15, 15, 14, 0, 16, 11, 14, + 3, 14, 14, 14, 5, 14, 7, 10, 14, 9, + 14, 6, 14, 14, 14, 15, 15, 0, 12, 14, + 14, 14, 14, 8, 14, 14, 0, 14, 14, 14, + 14, 14, 0, 14, 14, 14, 1, 13, 14, 14, + 14, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -378,14 +379,14 @@ static yyconst flex_int32_t yy_ec[256] = 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 1, 1, - 1, 1, 1, 1, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 16, 16, 19, 16, 20, 21, 16, - 16, 22, 23, 24, 25, 26, 16, 16, 27, 28, - 1, 1, 1, 1, 29, 1, 30, 31, 12, 32, + 1, 1, 1, 1, 10, 10, 10, 11, 12, 10, + 13, 13, 13, 13, 13, 13, 13, 14, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, + 1, 1, 1, 1, 16, 1, 17, 18, 10, 19, - 33, 34, 16, 35, 36, 16, 16, 37, 16, 38, - 39, 16, 16, 40, 41, 42, 43, 44, 16, 45, - 46, 47, 1, 1, 1, 1, 1, 1, 1, 1, + 20, 21, 13, 22, 23, 13, 13, 24, 13, 25, + 26, 13, 13, 27, 28, 29, 30, 31, 13, 32, + 33, 34, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -402,107 +403,96 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[48] = +static yyconst flex_int32_t yy_meta[35] = { 0, - 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 2, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[74] = +static yyconst flex_int16_t yy_base[78] = { 0, - 0, 0, 46, 48, 213, 198, 50, 238, 49, 54, - 197, 46, 51, 56, 58, 59, 63, 67, 65, 61, - 76, 0, 101, 187, 186, 104, 103, 106, 238, 118, - 113, 182, 115, 178, 176, 116, 171, 148, 117, 121, - 126, 0, 126, 142, 0, 123, 136, 140, 91, 142, - 87, 145, 238, 157, 146, 160, 84, 161, 152, 164, - 82, 193, 170, 163, 203, 173, 79, 72, 238, 232, - 78, 235, 68 + 0, 0, 33, 35, 163, 153, 37, 198, 36, 41, + 152, 42, 33, 38, 43, 44, 46, 49, 48, 53, + 50, 59, 62, 0, 64, 151, 142, 78, 78, 81, + 198, 94, 67, 87, 138, 85, 136, 135, 96, 133, + 88, 130, 97, 98, 103, 0, 108, 0, 0, 105, + 106, 111, 109, 113, 110, 112, 75, 116, 115, 125, + 126, 127, 58, 149, 129, 131, 198, 165, 132, 150, + 158, 198, 181, 185, 189, 60, 193 } ; -static yyconst flex_int16_t yy_def[74] = +static yyconst flex_int16_t yy_def[78] = { 0, - 69, 1, 70, 70, 69, 71, 69, 69, 71, 71, - 69, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 72, 72, 71, 69, 69, 71, 71, 69, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 72, 72, 69, 28, 71, 71, 71, 71, 71, - 71, 71, 69, 71, 71, 71, 71, 71, 71, 71, - 71, 73, 71, 71, 73, 71, 71, 71, 0, 69, - 69, 69, 69 + 72, 1, 73, 73, 72, 74, 72, 72, 74, 74, + 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 75, 75, 74, 72, 72, 74, 74, + 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 75, 75, 76, 30, 74, + 74, 74, 74, 74, 74, 74, 76, 74, 74, 74, + 74, 74, 72, 77, 74, 74, 72, 77, 74, 74, + 74, 0, 72, 72, 72, 72, 72 } ; -static yyconst flex_int16_t yy_nxt[286] = +static yyconst flex_int16_t yy_nxt[233] = { 0, 6, 7, 7, 8, 9, 6, 10, 9, 11, 6, - 6, 6, 12, 13, 14, 6, 6, 15, 6, 16, - 17, 6, 18, 19, 6, 6, 20, 21, 6, 6, - 6, 12, 13, 14, 6, 15, 6, 16, 17, 6, - 18, 19, 6, 6, 6, 20, 21, 23, 7, 23, - 7, 26, 26, 27, 25, 27, 27, 25, 27, 25, - 27, 27, 25, 30, 25, 33, 25, 25, 65, 25, - 31, 25, 34, 25, 40, 25, 32, 36, 24, 35, - 25, 30, 37, 38, 25, 33, 39, 25, 31, 41, - 25, 34, 25, 40, 32, 25, 36, 35, 28, 25, + 6, 6, 6, 6, 12, 6, 6, 6, 13, 14, + 15, 6, 16, 6, 17, 18, 19, 20, 21, 6, + 6, 6, 22, 23, 25, 7, 25, 7, 28, 28, + 29, 27, 29, 29, 27, 29, 27, 29, 29, 27, + 27, 27, 27, 32, 27, 33, 27, 27, 27, 36, + 57, 27, 34, 67, 37, 47, 28, 27, 35, 39, + 27, 38, 30, 40, 42, 27, 43, 41, 44, 28, + 28, 45, 29, 63, 29, 29, 27, 49, 49, 27, + 49, 49, 49, 27, 51, 27, 27, 49, 49, 49, - 37, 38, 43, 26, 39, 26, 26, 27, 41, 27, - 27, 25, 45, 45, 25, 45, 45, 45, 45, 45, - 45, 25, 47, 25, 25, 25, 25, 43, 26, 25, - 49, 25, 54, 48, 25, 45, 45, 45, 45, 45, - 46, 50, 47, 51, 25, 52, 55, 53, 25, 49, - 25, 48, 54, 25, 25, 57, 25, 58, 46, 50, - 25, 51, 56, 52, 60, 25, 55, 59, 25, 25, - 63, 25, 25, 61, 57, 67, 58, 64, 25, 25, - 56, 25, 60, 66, 25, 68, 25, 59, 63, 62, - 25, 44, 61, 24, 67, 25, 64, 24, 24, 24, + 49, 49, 27, 52, 27, 27, 27, 50, 53, 47, + 28, 27, 54, 27, 27, 58, 38, 27, 27, 27, + 27, 27, 59, 27, 27, 40, 55, 56, 60, 40, + 62, 64, 65, 27, 27, 27, 61, 27, 27, 27, + 27, 27, 64, 27, 27, 38, 27, 48, 66, 26, + 70, 71, 69, 26, 26, 26, 26, 27, 27, 27, + 31, 27, 72, 72, 26, 26, 27, 72, 40, 26, + 26, 26, 26, 27, 72, 72, 38, 72, 72, 72, + 26, 24, 24, 24, 24, 26, 72, 72, 26, 46, + 46, 72, 46, 68, 72, 72, 68, 5, 72, 72, - 24, 25, 66, 24, 68, 29, 25, 24, 24, 24, - 24, 25, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 24, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 24, 22, 22, 22, 42, 42, 5, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69 + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72 } ; -static yyconst flex_int16_t yy_chk[286] = +static yyconst flex_int16_t yy_chk[233] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, - 4, 7, 7, 9, 12, 9, 9, 9, 10, 13, - 10, 10, 10, 12, 14, 14, 15, 16, 73, 20, - 13, 17, 15, 19, 20, 18, 13, 17, 71, 16, - 68, 12, 17, 18, 21, 14, 19, 67, 13, 21, - 61, 15, 57, 20, 13, 51, 17, 16, 10, 49, + 1, 1, 1, 1, 3, 3, 4, 4, 7, 7, + 9, 13, 9, 9, 9, 10, 14, 10, 10, 10, + 12, 15, 16, 12, 17, 13, 19, 18, 21, 15, + 76, 20, 14, 63, 16, 25, 25, 22, 14, 18, + 23, 17, 10, 18, 20, 33, 21, 19, 22, 28, + 28, 23, 29, 57, 29, 29, 29, 30, 30, 30, + 30, 30, 30, 36, 33, 34, 41, 30, 30, 30, - 17, 18, 23, 23, 19, 26, 26, 27, 21, 27, - 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 31, 31, 33, 36, 39, 30, 43, 43, 40, - 36, 46, 46, 33, 41, 28, 28, 28, 28, 28, - 30, 39, 31, 40, 47, 41, 47, 44, 48, 36, - 50, 33, 46, 52, 55, 50, 38, 52, 30, 39, - 59, 40, 48, 41, 55, 54, 47, 54, 56, 58, - 59, 64, 60, 56, 50, 64, 52, 60, 63, 37, - 48, 66, 55, 63, 35, 66, 34, 54, 59, 58, - 32, 25, 56, 62, 64, 24, 60, 62, 62, 62, + 30, 30, 32, 34, 39, 43, 44, 32, 36, 47, + 47, 45, 41, 50, 51, 50, 39, 53, 55, 52, + 56, 54, 51, 59, 58, 44, 43, 45, 52, 55, + 56, 58, 59, 60, 61, 62, 53, 65, 42, 66, + 69, 40, 62, 38, 37, 61, 35, 27, 60, 64, + 66, 69, 65, 64, 64, 64, 64, 64, 70, 26, + 11, 6, 5, 0, 64, 68, 71, 0, 70, 68, + 68, 68, 68, 68, 0, 0, 71, 0, 0, 0, + 68, 73, 73, 73, 73, 74, 0, 0, 74, 75, + 75, 0, 75, 77, 0, 0, 77, 72, 72, 72, - 62, 62, 63, 65, 66, 11, 6, 65, 65, 65, - 65, 65, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65, 70, 70, 70, 72, 72, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - 69, 69, 69, 69, 69 + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72 } ; /* The intent behind this definition is that it'll catch @@ -512,8 +502,8 @@ static yyconst flex_int16_t yy_chk[286] = #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET -#line 1 "sapi/phpdbg/dev/phpdbg_lexer.l" -#line 2 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 2 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" /* * phpdbg_lexer.l @@ -524,21 +514,10 @@ static yyconst flex_int16_t yy_chk[286] = #define YYSTYPE phpdbg_param_t #include "phpdbg_parser.h" -#include -#include -static inline void phpdbg_append_string(phpdbg_param_t *param, const char *string, size_t length TSRMLS_DC) { - if (!param->str) { - param->str = malloc(length+1); - } else param->str = realloc(param->str, param->len + (length+1)); - - memcpy(¶m->str[param->len], string, length); - param->len += length; - param->str[param->len] = 0; -} #define YY_NO_UNISTD_H 1 -#line 542 "sapi/phpdbg/phpdbg_lexer.c" +#line 521 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -630,10 +609,6 @@ int yyget_lineno (yyscan_t yyscanner ); void yyset_lineno (int line_number ,yyscan_t yyscanner ); -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - YYSTYPE * yyget_lval (yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -680,7 +655,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -691,7 +666,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -776,9 +751,9 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 52 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 43 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 782 "sapi/phpdbg/phpdbg_lexer.c" +#line 757 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -833,13 +808,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 70 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 69 ); + while ( yy_current_state != 72 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -861,7 +836,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 54 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 45 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -871,22 +846,22 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 60 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 51 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } YY_BREAK case 3: YY_RULE_SETUP -#line 61 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 52 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } YY_BREAK case 4: YY_RULE_SETUP -#line 62 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 53 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } YY_BREAK case 5: YY_RULE_SETUP -#line 63 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 54 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -895,7 +870,7 @@ YY_RULE_SETUP YY_BREAK case 6: YY_RULE_SETUP -#line 68 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 59 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -904,7 +879,7 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 73 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 64 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -913,43 +888,52 @@ YY_RULE_SETUP YY_BREAK case 8: YY_RULE_SETUP -#line 78 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 69 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_RUN; + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 74 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } YY_BREAK -case 9: +case 10: YY_RULE_SETUP -#line 83 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 79 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 88 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 93 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 89 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 98 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -957,9 +941,9 @@ YY_RULE_SETUP return T_OPCODE; } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 104 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -968,9 +952,9 @@ YY_RULE_SETUP } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 112 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 108 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -979,18 +963,18 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 15: -/* rule 15 can match eol */ +case 16: +/* rule 16 can match eol */ YY_RULE_SETUP -#line 120 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 116 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 16: +case 17: YY_RULE_SETUP -#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 994 "sapi/phpdbg/phpdbg_lexer.c" +#line 978 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): yyterminate(); @@ -1186,7 +1170,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); @@ -1286,7 +1270,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 70 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1315,13 +1299,12 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 70 ) + if ( yy_current_state >= 73 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 69); + yy_is_jam = (yy_current_state == 72); - (void)yyg; return yy_is_jam ? 0 : yy_current_state; } @@ -1412,7 +1395,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) case EOB_ACT_END_OF_FILE: { if ( yywrap(yyscanner ) ) - return EOF; + return 0; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; @@ -1761,8 +1744,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -1770,8 +1753,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - yy_size_t i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -1917,7 +1899,7 @@ void yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); + yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); yylineno = line_number; } @@ -1932,7 +1914,7 @@ void yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - YY_FATAL_ERROR( "yyset_column called with no buffer" ); + yy_fatal_error( "yyset_column called with no buffer" , yyscanner); yycolumn = column_no; } @@ -2156,7 +2138,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 14dc12ef5a9..19f490f6ef8 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -13,7 +13,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 37 +#define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -51,6 +51,7 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -58,6 +59,7 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -88,8 +90,6 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! C99 */ - #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -214,7 +214,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(yyscanner) 1 +#define yywrap(n) 1 #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r @@ -270,10 +270,6 @@ int yyget_lineno (yyscan_t yyscanner ); void yyset_lineno (int line_number ,yyscan_t yyscanner ); -int yyget_column (yyscan_t yyscanner ); - -void yyset_column (int column_no ,yyscan_t yyscanner ); - YYSTYPE * yyget_lval (yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -339,9 +335,9 @@ extern int yylex \ #undef YY_DECL #endif -#line 121 "sapi/phpdbg/dev/phpdbg_lexer.l" +#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 346 "sapi/phpdbg/phpdbg_lexer.h" +#line 342 "sapi/phpdbg/phpdbg_lexer.h" #undef yyIN_HEADER #endif /* yyHEADER_H */ diff --git a/dev/phpdbg_lexer.l b/phpdbg_lexer.l similarity index 75% rename from dev/phpdbg_lexer.l rename to phpdbg_lexer.l index 577155c1c01..79dd35e7cd5 100644 --- a/dev/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -9,18 +9,7 @@ #define YYSTYPE phpdbg_param_t #include "phpdbg_parser.h" -#include -#include -static inline void phpdbg_append_string(phpdbg_param_t *param, const char *string, size_t length TSRMLS_DC) { - if (!param->str) { - param->str = malloc(length+1); - } else param->str = realloc(param->str, param->len + (length+1)); - - memcpy(¶m->str[param->len], string, length); - param->len += length; - param->str[param->len] = 0; -} %} %s RAW @@ -31,23 +20,25 @@ static inline void phpdbg_append_string(phpdbg_param_t *param, const char *strin %option reentrant noyywrap never-interactive nounistd %option bison-bridge -T_TRUE ?i:"true" -T_YES ?i:"yes" -T_ON ?i:"on" -T_ENABLED ?i:"enabled" -T_FALSE ?i:"false" -T_NO ?i:"no" -T_OFF ?i:"off" -T_DISABLED ?i:"disabled" -T_EVAL ?i:"ev" -T_SHELL ?i:"sh" -T_IF ?i:"if" +T_TRUE "true" +T_YES "yes" +T_ON "on" +T_ENABLED "enabled" +T_FALSE "false" +T_NO "no" +T_OFF "off" +T_DISABLED "disabled" +T_EVAL "ev" +T_SHELL "sh" +T_IF "if" +T_RUN "run" +T_RUN_SHORT "r" WS [ \r\n\t]+ DIGITS [0-9\.]+ ID [^ \r\n\t:#]+ ADDR 0x[a-fA-F0-9]+ -OPCODE ?i:ZEND_([A-Za-z])+ +OPCODE (ZEND_|zend_)([A-Za-z])+ INPUT [^\n]+ %% { @@ -75,6 +66,11 @@ INPUT [^\n]+ phpdbg_init_param(yylval, EMPTY_PARAM); return T_IF; } + {T_RUN}|{T_RUN_SHORT} { + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_RUN; + } {T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; diff --git a/phpdbg_parser.c b/phpdbg_parser.c deleted file mode 100644 index eabe78e7931..00000000000 --- a/phpdbg_parser.c +++ /dev/null @@ -1,1843 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.7" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* Copy the first part of user declarations. */ -/* Line 371 of yacc.c */ -#line 2 "sapi/phpdbg/dev/phpdbg_parser.y" - - -/* - * phpdbg_parser.y - * (from php-src root) - * flex sapi/phpdbg/dev/phpdbg_lexer.l - * bison sapi/phpdbg/dev/phpdbg_parser.y - */ - -#include "phpdbg.h" -#include "phpdbg_cmd.h" -#include "phpdbg_utils.h" -#include "phpdbg_cmd.h" -#include "phpdbg_prompt.h" - -#define YYSTYPE phpdbg_param_t - -#include "phpdbg_parser.h" -#include "phpdbg_lexer.h" - -ZEND_EXTERN_MODULE_GLOBALS(phpdbg); - -int yyerror(phpdbg_param_t *stack, yyscan_t scanner, const char *msg) { - TSRMLS_FETCH(); - phpdbg_error("Parse Error: %s", msg); - { - const phpdbg_param_t *top = stack; - - while (top) { - phpdbg_param_debug( - top, "--> "); - top = top->next; - } - } - return 0; -} - -/* Line 371 of yacc.c */ -#line 106 "sapi/phpdbg/phpdbg_parser.c" - -# ifndef YY_NULL -# if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr -# else -# define YY_NULL 0 -# endif -# endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* In a future release of Bison, this section will be replaced - by #include "phpdbg_parser.h". */ -#ifndef YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED -# define YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif -/* "%code requires" blocks. */ -/* Line 387 of yacc.c */ -#line 40 "sapi/phpdbg/dev/phpdbg_parser.y" - -#include "phpdbg.h" -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - - -/* Line 387 of yacc.c */ -#line 147 "sapi/phpdbg/phpdbg_parser.c" - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_EVAL = 258, - T_SHELL = 259, - T_IF = 260, - T_TRUTHY = 261, - T_FALSY = 262, - T_STRING = 263, - T_COLON = 264, - T_DCOLON = 265, - T_POUND = 266, - T_PROTO = 267, - T_DIGITS = 268, - T_LITERAL = 269, - T_ADDR = 270, - T_OPCODE = 271, - T_ID = 272, - T_INPUT = 273, - T_UNEXPECTED = 274 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (phpdbg_param_t *stack, yyscan_t scanner); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ - -/* Copy the second part of user declarations. */ - -/* Line 390 of yacc.c */ -#line 203 "sapi/phpdbg/phpdbg_parser.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) -#else -# define YYUSE(E) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 22 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 31 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 20 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 4 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 22 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 35 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 274 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 6, 8, 11, 15, 20, 25, - 31, 35, 41, 45, 48, 51, 54, 56, 58, 60, - 62, 64, 66 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 21, 0, -1, 22, -1, -1, 23, -1, 22, 23, - -1, 17, 9, 13, -1, 17, 9, 11, 13, -1, - 12, 17, 9, 13, -1, 12, 17, 9, 11, 13, - -1, 17, 10, 17, -1, 17, 10, 17, 11, 13, - -1, 17, 11, 13, -1, 5, 18, -1, 3, 18, - -1, 4, 18, -1, 16, -1, 15, -1, 14, -1, - 6, -1, 7, -1, 13, -1, 17, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 75, 75, 76, 80, 81, 85, 90, 95, 106, - 117, 122, 128, 134, 139, 144, 149, 150, 151, 152, - 153, 154, 155 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || 1 -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "\"eval\"", "\"shell\"", - "\"if (condition)\"", "\"truthy (true, on, yes or enabled)\"", - "\"falsy (false, off, no or disabled)\"", - "\"string (some input, perhaps)\"", "\": (colon)\"", - "\":: (double colon)\"", "\"# (pound sign)\"", "\"protocol (file://)\"", - "\"digits (numbers)\"", "\"literal (string)\"", "\"address\"", - "\"opcode\"", "\"identifier (command or function name)\"", - "\"input (input string or data)\"", "\"input\"", "$accept", "input", - "parameters", "parameter", YY_NULL -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 20, 21, 21, 22, 22, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 0, 1, 2, 3, 4, 4, 5, - 3, 5, 3, 2, 2, 2, 1, 1, 1, 1, - 1, 1, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 3, 0, 0, 0, 19, 20, 0, 21, 18, 17, - 16, 22, 0, 2, 4, 14, 15, 13, 0, 0, - 0, 0, 1, 5, 0, 0, 6, 10, 12, 0, - 8, 7, 0, 9, 11 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 12, 13, 14 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -11 -static const yytype_int8 yypact[] = -{ - -3, -10, 1, 2, -11, -11, 6, -11, -11, -11, - -11, -4, 21, -3, -11, -11, -11, -11, 13, 4, - 7, 12, -11, -11, 5, 14, -11, 15, -11, 16, - -11, -11, 17, -11, -11 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -11, -11, -11, 18 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 1, 2, 3, 4, 5, 19, 20, 21, 15, 6, - 7, 8, 9, 10, 11, 25, 29, 26, 30, 16, - 17, 22, 24, 18, 27, 28, 32, 31, 0, 33, - 34, 23 -}; - -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-11))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int8 yycheck[] = -{ - 3, 4, 5, 6, 7, 9, 10, 11, 18, 12, - 13, 14, 15, 16, 17, 11, 11, 13, 13, 18, - 18, 0, 9, 17, 17, 13, 11, 13, -1, 13, - 13, 13 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 4, 5, 6, 7, 12, 13, 14, 15, - 16, 17, 21, 22, 23, 18, 18, 18, 17, 9, - 10, 11, 0, 23, 9, 11, 13, 17, 13, 11, - 13, 13, 11, 13, 13 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (stack, scanner, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - -/* Error token number */ -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* This macro is provided for backward compatibility. */ -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, scanner) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, stack, scanner); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - phpdbg_param_t *stack; - yyscan_t scanner; -#endif -{ - FILE *yyo = yyoutput; - YYUSE (yyo); - if (!yyvaluep) - return; - YYUSE (stack); - YYUSE (scanner); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, stack, scanner) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - phpdbg_param_t *stack; - yyscan_t scanner; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep, stack, scanner); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule, phpdbg_param_t *stack, yyscan_t scanner) -#else -static void -yy_reduce_print (yyvsp, yyrule, stack, scanner) - YYSTYPE *yyvsp; - int yyrule; - phpdbg_param_t *stack; - yyscan_t scanner; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , stack, scanner); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule, stack, scanner); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. - - Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return 2 if the - required number of bytes is too large to store. */ -static int -yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, - yytype_int16 *yyssp, int yytoken) -{ - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); - YYSIZE_T yysize = yysize0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULL; - /* Arguments of yyformat. */ - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - /* Number of reported tokens (one for the "unexpected", one per - "expected"). */ - int yycount = 0; - - /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - - Of course, the expected token list depends on states to have - correct lookahead information, and it depends on the parser not - to perform extra reductions after fetching a lookahead from the - scanner and before detecting a syntax error. Thus, state merging - (from LALR or IELR) and default reductions corrupt the expected - token list. However, the list is correct for canonical LR with - one exception: it will still contain any token that will not be - accepted due to an error action in a later state. - */ - if (yytoken != YYEMPTY) - { - int yyn = yypact[*yyssp]; - yyarg[yycount++] = yytname[yytoken]; - if (!yypact_value_is_default (yyn)) - { - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. In other words, skip the first -YYN actions for - this state because they are default actions. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yyx; - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR - && !yytable_value_is_error (yytable[yyx + yyn])) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - break; - } - yyarg[yycount++] = yytname[yyx]; - { - YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - } - } - } - - switch (yycount) - { -# define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -# undef YYCASE_ - } - - { - YYSIZE_T yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return 1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyformat += 2; - } - else - { - yyp++; - yyformat++; - } - } - return 0; -} -#endif /* YYERROR_VERBOSE */ - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, phpdbg_param_t *stack, yyscan_t scanner) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, stack, scanner) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - phpdbg_param_t *stack; - yyscan_t scanner; -#endif -{ - YYUSE (yyvaluep); - YYUSE (stack); - YYUSE (scanner); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (phpdbg_param_t *stack, yyscan_t scanner) -#else -int -yyparse (stack, scanner) - phpdbg_param_t *stack; - yyscan_t scanner; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - - -#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -/* Default value used for initialization, for pacifying older GCCs - or non-GCC compilers. */ -static YYSTYPE yyval_default; -# define YY_INITIAL_VALUE(Value) = Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yyssp = yyss = yyssa; - yyvsp = yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: -/* Line 1792 of yacc.c */ -#line 80 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(1) - (1)])); } - break; - - case 5: -/* Line 1792 of yacc.c */ -#line 81 "sapi/phpdbg/dev/phpdbg_parser.y" - { phpdbg_stack_push(stack, &(yyvsp[(2) - (2)])); } - break; - - case 6: -/* Line 1792 of yacc.c */ -#line 85 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = FILE_PARAM; - (yyval).file.name = (yyvsp[(2) - (3)]).str; - (yyval).file.line = (yyvsp[(3) - (3)]).num; - } - break; - - case 7: -/* Line 1792 of yacc.c */ -#line 90 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = NUMERIC_FILE_PARAM; - (yyval).file.name = (yyvsp[(1) - (4)]).str; - (yyval).file.line = (yyvsp[(4) - (4)]).num; - } - break; - - case 8: -/* Line 1792 of yacc.c */ -#line 95 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = FILE_PARAM; - (yyval).file.name = malloc((yyvsp[(1) - (4)]).len + - (yyvsp[(2) - (4)]).len + 1); - if ((yyval).file.name) { - memcpy(&(yyval).file.name[0], (yyvsp[(1) - (4)]).str, (yyvsp[(1) - (4)]).len); - memcpy(&(yyval).file.name[(yyvsp[(1) - (4)]).len], (yyvsp[(2) - (4)]).str, (yyvsp[(2) - (4)]).len); - (yyval).file.name[(yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len] = '\0'; - } - (yyval).file.line = (yyvsp[(4) - (4)]).num; - } - break; - - case 9: -/* Line 1792 of yacc.c */ -#line 106 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = NUMERIC_FILE_PARAM; - (yyval).file.name = malloc((yyvsp[(1) - (5)]).len + - (yyvsp[(2) - (5)]).len + 1); - if ((yyval).file.name) { - memcpy(&(yyval).file.name[0], (yyvsp[(1) - (5)]).str, (yyvsp[(1) - (5)]).len); - memcpy(&(yyval).file.name[(yyvsp[(1) - (5)]).len], (yyvsp[(2) - (5)]).str, (yyvsp[(2) - (5)]).len); - (yyval).file.name[(yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len] = '\0'; - } - (yyval).file.line = (yyvsp[(5) - (5)]).num; - } - break; - - case 10: -/* Line 1792 of yacc.c */ -#line 117 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = METHOD_PARAM; - (yyval).method.class = (yyvsp[(1) - (3)]).str; - (yyval).method.name = (yyvsp[(3) - (3)]).str; - } - break; - - case 11: -/* Line 1792 of yacc.c */ -#line 122 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = NUMERIC_METHOD_PARAM; - (yyval).method.class = (yyvsp[(1) - (5)]).str; - (yyval).method.name = (yyvsp[(3) - (5)]).str; - (yyval).num = (yyvsp[(5) - (5)]).num; - } - break; - - case 12: -/* Line 1792 of yacc.c */ -#line 128 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = NUMERIC_FUNCTION_PARAM; - (yyval).str = (yyvsp[(1) - (3)]).str; - (yyval).len = (yyvsp[(1) - (3)]).len; - (yyval).num = (yyvsp[(3) - (3)]).num; - } - break; - - case 13: -/* Line 1792 of yacc.c */ -#line 134 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = COND_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } - break; - - case 14: -/* Line 1792 of yacc.c */ -#line 139 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = EVAL_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } - break; - - case 15: -/* Line 1792 of yacc.c */ -#line 144 "sapi/phpdbg/dev/phpdbg_parser.y" - { - (yyval).type = SHELL_PARAM; - (yyval).str = (yyvsp[(2) - (2)]).str; - (yyval).len = (yyvsp[(2) - (2)]).len; - } - break; - - case 16: -/* Line 1792 of yacc.c */ -#line 149 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 17: -/* Line 1792 of yacc.c */ -#line 150 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 18: -/* Line 1792 of yacc.c */ -#line 151 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 19: -/* Line 1792 of yacc.c */ -#line 152 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 20: -/* Line 1792 of yacc.c */ -#line 153 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 21: -/* Line 1792 of yacc.c */ -#line 154 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - case 22: -/* Line 1792 of yacc.c */ -#line 155 "sapi/phpdbg/dev/phpdbg_parser.y" - { (yyval) = (yyvsp[(1) - (1)]); } - break; - - -/* Line 1792 of yacc.c */ -#line 1611 "sapi/phpdbg/phpdbg_parser.c" - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); - - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (stack, scanner, YY_("syntax error")); -#else -# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ - yyssp, yytoken) - { - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - yysyntax_error_status = YYSYNTAX_ERROR; - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == 1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); - if (!yymsg) - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = 2; - } - else - { - yysyntax_error_status = YYSYNTAX_ERROR; - yymsgp = yymsg; - } - } - yyerror (stack, scanner, yymsgp); - if (yysyntax_error_status == 2) - goto yyexhaustedlab; - } -# undef YYSYNTAX_ERROR -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, stack, scanner); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp, stack, scanner); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined yyoverflow || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (stack, scanner, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, stack, scanner); - } - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, stack, scanner); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -/* Line 2055 of yacc.c */ -#line 158 "sapi/phpdbg/dev/phpdbg_parser.y" - diff --git a/phpdbg_parser.h b/phpdbg_parser.h deleted file mode 100644 index 3a57a5e54ff..00000000000 --- a/phpdbg_parser.h +++ /dev/null @@ -1,105 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.7. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -#ifndef YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED -# define YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif -/* "%code requires" blocks. */ -/* Line 2058 of yacc.c */ -#line 40 "sapi/phpdbg/dev/phpdbg_parser.y" - -#include "phpdbg.h" -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - - -/* Line 2058 of yacc.c */ -#line 55 "sapi/phpdbg/phpdbg_parser.h" - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_EVAL = 258, - T_SHELL = 259, - T_IF = 260, - T_TRUTHY = 261, - T_FALSY = 262, - T_STRING = 263, - T_COLON = 264, - T_DCOLON = 265, - T_POUND = 266, - T_PROTO = 267, - T_DIGITS = 268, - T_LITERAL = 269, - T_ADDR = 270, - T_OPCODE = 271, - T_ID = 272, - T_INPUT = 273, - T_UNEXPECTED = 274 - }; -#endif - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (phpdbg_param_t *stack, yyscan_t scanner); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - -#endif /* !YY_YY_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ diff --git a/dev/phpdbg_parser.y b/phpdbg_parser.y similarity index 97% rename from dev/phpdbg_parser.y rename to phpdbg_parser.y index 58306e07f91..b1b2423fb1f 100644 --- a/dev/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -53,6 +53,7 @@ typedef void* yyscan_t; %parse-param { yyscan_t scanner } %token T_EVAL "eval" +%token T_RUN "run" %token T_SHELL "shell" %token T_IF "if (condition)" %token T_TRUTHY "truthy (true, on, yes or enabled)" @@ -146,6 +147,11 @@ parameter $$.str = $2.str; $$.len = $2.len; } + | T_RUN T_INPUT { + $$.type = RUN_PARAM; + $$.str = $2.str; + $$.len = $2.len; + } | T_OPCODE { $$ = $1; } | T_ADDR { $$ = $1; } | T_LITERAL { $$ = $1; } From 2ab2b74af3344f076248c5c5574c7b814a2b44fc Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 16 Apr 2014 20:55:02 +0200 Subject: [PATCH 122/137] Also check for length to not segfault --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 86fc4d718e5..da06c71aff1 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -645,7 +645,7 @@ PHPDBG_COMMAND(run) /* {{{ */ /* reset hit counters */ phpdbg_reset_breakpoints(TSRMLS_C); - if (param && param->type != EMPTY_PARAM) { + if (param && param->type != EMPTY_PARAM && param->len != 0) { char **argv = emalloc(5 * sizeof(char *)); int argc = 0; int i; From 58c3f7e6992737948be26d46a869dd7c465cbd56 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 16 Apr 2014 20:55:29 +0200 Subject: [PATCH 123/137] command tokens just available at the beginning now --- phpdbg_lexer.c | 560 +++++++++++++++++++++++++++++------------------- phpdbg_lexer.h | 5 +- phpdbg_lexer.l | 42 ++-- phpdbg_parser.y | 4 + 4 files changed, 380 insertions(+), 231 deletions(-) diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index fc8d846b73b..f3244905a1f 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -350,8 +350,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 17 -#define YY_END_OF_BUFFER 18 +#define YY_NUM_RULES 18 +#define YY_END_OF_BUFFER 19 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -359,16 +359,51 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[73] = +static yyconst flex_int16_t yy_acclist[231] = { 0, - 0, 0, 0, 0, 18, 14, 16, 2, 11, 11, - 4, 14, 14, 14, 14, 14, 14, 14, 8, 14, - 14, 14, 14, 15, 15, 14, 0, 16, 11, 14, - 3, 14, 14, 14, 5, 14, 7, 10, 14, 9, - 14, 6, 14, 14, 14, 15, 15, 0, 12, 14, - 14, 14, 14, 8, 14, 14, 0, 14, 14, 14, - 14, 14, 0, 14, 14, 14, 1, 13, 14, 14, - 14, 0 + 19, 4, 15, 18, 4, 17, 18, 17, 18, 4, + 7, 18, 4, 12, 15, 18, 4, 12, 15, 18, + 4, 9, 18, 4, 15, 18, 4, 15, 18, 4, + 15, 18, 4, 15, 18, 4, 15, 18, 4, 15, + 18, 3, 4, 15, 18, 4, 15, 18, 4, 15, + 18, 4, 15, 18, 4, 15, 18, 16, 18, 16, + 17, 18, 15, 18, 7, 18, 12, 15, 18, 12, + 15, 18, 9, 18, 15, 18, 15, 18, 15, 18, + 15, 18, 15, 18, 15, 18, 15, 18, 15, 18, + 15, 18, 15, 18, 4, 15, 4, 4, 4, 17, + + 17, 4, 12, 15, 4, 15, 4, 8, 4, 15, + 4, 15, 4, 15, 1, 4, 15, 4, 15, 4, + 11, 15, 4, 15, 4, 10, 15, 4, 15, 2, + 4, 15, 4, 15, 4, 15, 4, 15, 16, 16, + 17, 15, 12, 15, 15, 8, 15, 15, 15, 15, + 5, 15, 11, 15, 15, 10, 15, 15, 15, 15, + 4, 4, 13, 15, 4, 15, 4, 15, 4, 15, + 4, 15, 3, 4, 15, 4, 15, 4, 15, 13, + 15, 15, 15, 15, 15, 15, 15, 4, 4, 15, + 4, 15, 4, 15, 4, 15, 4, 15, 15, 15, + + 15, 15, 15, 4, 4, 15, 4, 15, 4, 15, + 15, 15, 15, 4, 6, 4, 14, 15, 4, 15, + 4, 15, 6, 14, 15, 15, 15, 4, 15, 15 + } ; + +static yyconst flex_int16_t yy_accept[131] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 2, 5, 8, + 10, 13, 17, 21, 24, 27, 30, 33, 36, 39, + 42, 46, 49, 52, 55, 58, 60, 63, 65, 67, + 70, 73, 75, 77, 79, 81, 83, 85, 87, 89, + 91, 93, 95, 97, 98, 99, 101, 102, 105, 107, + 109, 111, 113, 115, 118, 120, 123, 125, 128, 130, + 133, 135, 137, 139, 140, 142, 143, 143, 145, 146, + 147, 148, 149, 150, 151, 153, 155, 156, 158, 159, + 160, 161, 162, 165, 167, 169, 171, 173, 176, 178, + 180, 180, 182, 183, 184, 185, 186, 187, 188, 189, + + 191, 193, 195, 197, 199, 199, 200, 201, 202, 203, + 204, 205, 207, 209, 211, 211, 212, 213, 214, 216, + 219, 221, 223, 224, 226, 227, 228, 230, 231, 231 } ; static yyconst flex_int32_t yy_ec[256] = @@ -411,94 +446,174 @@ static yyconst flex_int32_t yy_meta[35] = 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[78] = +static yyconst flex_int16_t yy_base[139] = { 0, - 0, 0, 33, 35, 163, 153, 37, 198, 36, 41, - 152, 42, 33, 38, 43, 44, 46, 49, 48, 53, - 50, 59, 62, 0, 64, 151, 142, 78, 78, 81, - 198, 94, 67, 87, 138, 85, 136, 135, 96, 133, - 88, 130, 97, 98, 103, 0, 108, 0, 0, 105, - 106, 111, 109, 113, 110, 112, 75, 116, 115, 125, - 126, 127, 58, 149, 129, 131, 198, 165, 132, 150, - 158, 198, 181, 185, 189, 60, 193 + 0, 0, 33, 35, 38, 0, 385, 71, 74, 76, + 378, 79, 87, 90, 96, 100, 108, 109, 112, 120, + 123, 126, 138, 142, 148, 0, 104, 356, 479, 151, + 162, 351, 73, 92, 65, 146, 122, 94, 152, 127, + 155, 163, 172, 354, 131, 176, 182, 324, 190, 319, + 178, 184, 187, 211, 212, 215, 221, 224, 225, 235, + 236, 239, 245, 0, 203, 260, 259, 248, 264, 479, + 237, 190, 243, 253, 255, 222, 259, 194, 249, 250, + 277, 285, 0, 286, 289, 299, 303, 307, 316, 319, + 0, 0, 252, 283, 295, 287, 290, 305, 325, 328, + + 331, 337, 343, 346, 181, 310, 333, 334, 344, 350, + 229, 366, 374, 375, 160, 398, 345, 371, 146, 414, + 388, 392, 479, 430, 380, 393, 423, 415, 479, 446, + 450, 454, 458, 462, 466, 96, 470, 474 } ; -static yyconst flex_int16_t yy_def[78] = +static yyconst flex_int16_t yy_def[139] = { 0, - 72, 1, 73, 73, 72, 74, 72, 72, 74, 74, - 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 75, 75, 74, 72, 72, 74, 74, - 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 75, 75, 76, 30, 74, - 74, 74, 74, 74, 74, 74, 76, 74, 74, 74, - 74, 74, 72, 77, 74, 74, 72, 77, 74, 74, - 74, 0, 72, 72, 72, 72, 72 + 129, 1, 130, 130, 129, 5, 129, 131, 132, 129, + 132, 131, 131, 132, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 133, 133, 134, 129, 134, + 134, 129, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 134, 131, 132, 132, 132, 129, 13, 13, 132, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 133, 133, 134, 129, 134, 134, 129, + 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, + 134, 135, 49, 131, 131, 131, 131, 131, 131, 131, + 136, 69, 134, 134, 134, 134, 134, 134, 135, 131, + + 131, 131, 131, 131, 136, 134, 134, 134, 134, 134, + 132, 137, 131, 131, 129, 138, 134, 134, 132, 137, + 131, 131, 129, 138, 134, 134, 131, 134, 0, 129, + 129, 129, 129, 129, 129, 129, 129, 129 } ; -static yyconst flex_int16_t yy_nxt[233] = +static yyconst flex_int16_t yy_nxt[514] = { 0, - 6, 7, 7, 8, 9, 6, 10, 9, 11, 6, - 6, 6, 6, 6, 12, 6, 6, 6, 13, 14, - 15, 6, 16, 6, 17, 18, 19, 20, 21, 6, - 6, 6, 22, 23, 25, 7, 25, 7, 28, 28, - 29, 27, 29, 29, 27, 29, 27, 29, 29, 27, - 27, 27, 27, 32, 27, 33, 27, 27, 27, 36, - 57, 27, 34, 67, 37, 47, 28, 27, 35, 39, - 27, 38, 30, 40, 42, 27, 43, 41, 44, 28, - 28, 45, 29, 63, 29, 29, 27, 49, 49, 27, - 49, 49, 49, 27, 51, 27, 27, 49, 49, 49, + 8, 9, 10, 11, 12, 8, 13, 12, 14, 8, + 8, 8, 8, 8, 15, 8, 8, 8, 16, 17, + 18, 8, 8, 8, 19, 20, 21, 22, 23, 8, + 8, 8, 24, 25, 27, 10, 27, 10, 28, 10, + 10, 29, 30, 28, 31, 30, 32, 28, 28, 28, + 28, 28, 33, 28, 28, 28, 34, 35, 36, 28, + 37, 28, 38, 39, 28, 28, 40, 28, 28, 28, + 41, 42, 44, 67, 44, 46, 47, 47, 47, 45, + 44, 67, 44, 48, 71, 48, 48, 45, 44, 73, + 44, 48, 129, 48, 48, 45, 105, 44, 50, 44, - 49, 49, 27, 52, 27, 27, 27, 50, 53, 47, - 28, 27, 54, 27, 27, 58, 38, 27, 27, 27, - 27, 27, 59, 27, 27, 40, 55, 56, 60, 40, - 62, 64, 65, 27, 27, 27, 61, 27, 27, 27, - 27, 27, 64, 27, 27, 38, 27, 48, 66, 26, - 70, 71, 69, 26, 26, 26, 26, 27, 27, 27, - 31, 27, 72, 72, 26, 26, 27, 72, 40, 26, - 26, 26, 26, 27, 72, 72, 38, 72, 72, 72, - 26, 24, 24, 24, 24, 26, 72, 72, 26, 46, - 46, 72, 46, 68, 72, 72, 68, 5, 72, 72, + 67, 44, 67, 44, 45, 65, 47, 51, 45, 44, + 44, 44, 44, 44, 72, 44, 45, 45, 49, 76, + 45, 44, 52, 44, 44, 55, 44, 44, 45, 44, + 67, 45, 53, 129, 45, 67, 82, 56, 54, 44, + 57, 44, 75, 44, 58, 44, 45, 60, 129, 44, + 45, 44, 59, 79, 67, 68, 45, 68, 68, 67, + 67, 62, 74, 67, 61, 123, 68, 63, 68, 68, + 67, 67, 77, 44, 80, 44, 78, 46, 47, 44, + 45, 44, 81, 47, 47, 44, 45, 44, 44, 115, + 44, 84, 45, 69, 43, 45, 83, 83, 67, 83, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72 + 83, 83, 67, 86, 65, 47, 83, 83, 83, 83, + 83, 85, 44, 44, 44, 44, 44, 94, 44, 45, + 45, 43, 44, 45, 44, 44, 44, 44, 44, 45, + 67, 129, 45, 45, 119, 87, 44, 44, 44, 44, + 44, 56, 44, 45, 45, 67, 44, 45, 44, 88, + 93, 67, 68, 45, 68, 68, 67, 67, 67, 95, + 67, 67, 106, 67, 91, 89, 58, 67, 67, 90, + 92, 92, 67, 92, 92, 92, 96, 78, 97, 76, + 92, 92, 92, 92, 92, 67, 44, 44, 44, 44, + 44, 67, 44, 44, 45, 67, 100, 45, 67, 107, + + 44, 98, 44, 67, 44, 101, 44, 45, 44, 78, + 44, 45, 108, 67, 109, 45, 102, 44, 67, 44, + 44, 129, 44, 110, 45, 116, 44, 45, 44, 44, + 103, 44, 44, 111, 44, 58, 45, 104, 44, 45, + 44, 67, 67, 112, 44, 45, 44, 44, 113, 44, + 117, 45, 67, 67, 45, 43, 129, 118, 67, 70, + 114, 112, 56, 76, 67, 116, 43, 44, 125, 44, + 43, 43, 43, 43, 45, 44, 44, 44, 44, 67, + 129, 43, 45, 45, 129, 129, 129, 129, 67, 44, + 126, 44, 129, 44, 122, 44, 45, 121, 66, 128, + + 45, 67, 66, 66, 66, 66, 67, 127, 129, 129, + 58, 78, 129, 66, 43, 44, 129, 44, 43, 43, + 43, 43, 45, 67, 44, 129, 44, 129, 129, 43, + 66, 45, 129, 76, 66, 66, 66, 66, 67, 129, + 129, 56, 129, 129, 129, 66, 26, 26, 26, 26, + 43, 43, 129, 43, 44, 44, 44, 44, 64, 64, + 129, 64, 66, 129, 129, 66, 99, 99, 129, 99, + 120, 120, 129, 120, 124, 129, 129, 124, 7, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129 } ; -static yyconst flex_int16_t yy_chk[233] = +static yyconst flex_int16_t yy_chk[514] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 4, 4, 7, 7, - 9, 13, 9, 9, 9, 10, 14, 10, 10, 10, - 12, 15, 16, 12, 17, 13, 19, 18, 21, 15, - 76, 20, 14, 63, 16, 25, 25, 22, 14, 18, - 23, 17, 10, 18, 20, 33, 21, 19, 22, 28, - 28, 23, 29, 57, 29, 29, 29, 30, 30, 30, - 30, 30, 30, 36, 33, 34, 41, 30, 30, 30, + 1, 1, 1, 1, 3, 3, 4, 4, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 8, 35, 8, 9, 9, 10, 10, 8, + 12, 33, 12, 12, 33, 12, 12, 12, 13, 35, + 13, 13, 14, 13, 13, 13, 136, 15, 14, 15, - 30, 30, 32, 34, 39, 43, 44, 32, 36, 47, - 47, 45, 41, 50, 51, 50, 39, 53, 55, 52, - 56, 54, 51, 59, 58, 44, 43, 45, 52, 55, - 56, 58, 59, 60, 61, 62, 53, 65, 42, 66, - 69, 40, 62, 38, 37, 61, 35, 27, 60, 64, - 66, 69, 65, 64, 64, 64, 64, 64, 70, 26, - 11, 6, 5, 0, 64, 68, 71, 0, 70, 68, - 68, 68, 68, 68, 0, 0, 71, 0, 0, 0, - 68, 73, 73, 73, 73, 74, 0, 0, 74, 75, - 75, 0, 75, 77, 0, 0, 77, 72, 72, 72, + 34, 16, 38, 16, 15, 27, 27, 15, 16, 17, + 18, 17, 18, 19, 34, 19, 17, 18, 13, 38, + 19, 20, 16, 20, 21, 18, 21, 22, 20, 22, + 37, 21, 17, 45, 22, 40, 45, 19, 17, 23, + 20, 23, 37, 24, 20, 24, 23, 22, 119, 25, + 24, 25, 21, 40, 36, 30, 25, 30, 30, 30, + 39, 24, 36, 41, 23, 115, 31, 25, 31, 31, + 31, 42, 39, 43, 41, 43, 39, 46, 46, 51, + 43, 51, 42, 47, 47, 52, 51, 52, 53, 105, + 53, 51, 52, 31, 49, 53, 49, 49, 72, 49, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, - 72, 72 + 49, 49, 78, 53, 65, 65, 49, 49, 49, 49, + 49, 52, 54, 55, 54, 55, 56, 72, 56, 54, + 55, 49, 57, 56, 57, 58, 59, 58, 59, 57, + 76, 111, 58, 59, 111, 55, 60, 61, 60, 61, + 62, 57, 62, 60, 61, 71, 63, 62, 63, 59, + 71, 73, 68, 63, 68, 68, 68, 79, 80, 73, + 93, 74, 93, 75, 67, 61, 62, 77, 66, 63, + 69, 69, 69, 69, 69, 69, 74, 80, 79, 77, + 69, 69, 69, 69, 69, 81, 82, 84, 82, 84, + 85, 94, 85, 82, 84, 96, 84, 85, 97, 94, + + 86, 81, 86, 95, 87, 85, 87, 86, 88, 97, + 88, 87, 95, 98, 96, 88, 86, 89, 106, 89, + 90, 50, 90, 98, 89, 106, 99, 90, 99, 100, + 87, 100, 101, 99, 101, 89, 100, 90, 102, 101, + 102, 107, 108, 100, 103, 102, 103, 104, 101, 104, + 107, 103, 109, 117, 104, 48, 44, 108, 110, 32, + 102, 104, 103, 109, 28, 110, 112, 112, 117, 112, + 112, 112, 112, 112, 112, 113, 114, 113, 114, 118, + 11, 112, 113, 114, 7, 0, 0, 0, 125, 121, + 118, 121, 0, 122, 114, 122, 121, 113, 116, 125, + + 122, 126, 116, 116, 116, 116, 116, 121, 0, 0, + 122, 126, 0, 116, 120, 120, 0, 120, 120, 120, + 120, 120, 120, 128, 127, 0, 127, 0, 0, 120, + 124, 127, 0, 128, 124, 124, 124, 124, 124, 0, + 0, 127, 0, 0, 0, 124, 130, 130, 130, 130, + 131, 131, 0, 131, 132, 132, 132, 132, 133, 133, + 0, 133, 134, 0, 0, 134, 135, 135, 0, 135, + 137, 137, 0, 137, 138, 0, 0, 138, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + + 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129 } ; -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected +#define REJECT \ +{ \ +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ \ +yy_cp = yyg->yy_full_match; /* restore poss. backed-over text */ \ +++yyg->yy_lp; \ +goto find_rule; \ +} + #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET @@ -516,11 +631,13 @@ static yyconst flex_int16_t yy_chk[233] = #include "phpdbg_parser.h" + #define YY_NO_UNISTD_H 1 -#line 521 "sapi/phpdbg/phpdbg_lexer.c" +#line 637 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 +#define NORMAL 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way @@ -562,6 +679,17 @@ struct yyguts_t int yylineno_r; int yy_flex_debug_r; + yy_state_type *yy_state_buf; + yy_state_type *yy_state_ptr; + char *yy_full_match; + int yy_lp; + + /* These are only needed for trailing context rules, + * but there's no conditional variable for that yet. */ + int yy_looking_for_trail_begin; + int yy_full_lp; + int *yy_full_state; + char *yytext_r; int yy_more_flag; int yy_more_len; @@ -751,9 +879,10 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 43 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 44 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 757 "sapi/phpdbg/phpdbg_lexer.c" + +#line 886 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -765,6 +894,12 @@ YY_DECL YY_USER_INIT; #endif + /* Create the reject buffer large enough to save one state per allowed character. */ + if ( ! yyg->yy_state_buf ) + yyg->yy_state_buf = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE ,yyscanner); + if ( ! yyg->yy_state_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yylex()" ); + if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ @@ -796,30 +931,45 @@ YY_DECL yy_bp = yy_cp; yy_current_state = yyg->yy_start; + + yyg->yy_state_ptr = yyg->yy_state_buf; + *yyg->yy_state_ptr++ = yy_current_state; + yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 130 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yyg->yy_state_ptr++ = yy_current_state; ++yy_cp; } - while ( yy_current_state != 72 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; + while ( yy_current_state != 129 ); yy_find_action: - yy_act = yy_accept[yy_current_state]; + yy_current_state = *--yyg->yy_state_ptr; + yyg->yy_lp = yy_accept[yy_current_state]; +goto find_rule; /* Shut up GCC warning -Wall */ +find_rule: /* we branch to this label when backing up */ + for ( ; ; ) /* until we find what rule we matched */ + { + if ( yyg->yy_lp && yyg->yy_lp < yy_accept[yy_current_state + 1] ) + { + yy_act = yy_acclist[yyg->yy_lp]; + { + yyg->yy_full_match = yy_cp; + break; + } + } + --yy_cp; + yy_current_state = *--yyg->yy_state_ptr; + yyg->yy_lp = yy_accept[yy_current_state]; + } YY_DO_BEFORE_ACTION; @@ -827,16 +977,58 @@ do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; case 1: YY_RULE_SETUP -#line 45 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 47 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_EVAL; + } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 52 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_SHELL; + } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 57 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_RUN; + } + YY_BREAK +case 4: +YY_RULE_SETUP +#line 63 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(NORMAL); + REJECT; + } + YY_BREAK + + +case 5: +YY_RULE_SETUP +#line 70 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_IF; + } + YY_BREAK + + +case 6: +YY_RULE_SETUP +#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -844,96 +1036,60 @@ YY_RULE_SETUP return T_PROTO; } YY_BREAK -case 2: -YY_RULE_SETUP -#line 51 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ return T_POUND; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 52 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ return T_DCOLON; } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 53 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ return T_COLON; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 54 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_EVAL; - } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 59 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_SHELL; - } - YY_BREAK case 7: YY_RULE_SETUP -#line 64 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_IF; - } +#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ return T_POUND; } YY_BREAK case 8: YY_RULE_SETUP -#line 69 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -{ - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_RUN; - } +#line 85 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ return T_DCOLON; } YY_BREAK case 9: YY_RULE_SETUP -#line 74 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 86 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +{ return T_COLON; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 88 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; return T_TRUTHY; } YY_BREAK -case 10: +case 11: YY_RULE_SETUP -#line 79 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 93 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; return T_FALSY; } YY_BREAK -case 11: +case 12: YY_RULE_SETUP -#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 98 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); return T_DIGITS; } YY_BREAK -case 12: +case 13: YY_RULE_SETUP -#line 89 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 103 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); return T_ADDR; } YY_BREAK -case 13: +case 14: YY_RULE_SETUP -#line 94 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 108 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -941,9 +1097,9 @@ YY_RULE_SETUP return T_OPCODE; } YY_BREAK -case 14: +case 15: YY_RULE_SETUP -#line 100 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 114 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -952,9 +1108,9 @@ YY_RULE_SETUP } YY_BREAK -case 15: +case 16: YY_RULE_SETUP -#line 108 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 122 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -963,21 +1119,22 @@ YY_RULE_SETUP return T_INPUT; } YY_BREAK -case 16: -/* rule 16 can match eol */ +case 17: +/* rule 17 can match eol */ YY_RULE_SETUP -#line 116 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 130 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK -case 17: +case 18: YY_RULE_SETUP -#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 978 "sapi/phpdbg/phpdbg_lexer.c" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(RAW): - yyterminate(); +#line 1134 "sapi/phpdbg/phpdbg_lexer.c" + case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(RAW): + case YY_STATE_EOF(NORMAL): + yyterminate(); case YY_END_OF_BUFFER: { @@ -1042,8 +1199,7 @@ case YY_STATE_EOF(RAW): else { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; + yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } @@ -1169,37 +1325,8 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); } @@ -1259,21 +1386,20 @@ static int yy_get_next_buffer (yyscan_t yyscanner) yy_current_state = yyg->yy_start; + yyg->yy_state_ptr = yyg->yy_state_buf; + *yyg->yy_state_ptr++ = yy_current_state; + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 130 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + *yyg->yy_state_ptr++ = yy_current_state; } return yy_current_state; @@ -1288,22 +1414,18 @@ static int yy_get_next_buffer (yyscan_t yyscanner) { register int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 73 ) + if ( yy_current_state >= 130 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 72); + yy_is_jam = (yy_current_state == 129); + if ( ! yy_is_jam ) + *yyg->yy_state_ptr++ = yy_current_state; return yy_is_jam ? 0 : yy_current_state; } @@ -2045,6 +2167,11 @@ static int yy_init_globals (yyscan_t yyscanner) yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; + yyg->yy_state_buf = 0; + yyg->yy_state_ptr = 0; + yyg->yy_full_match = 0; + yyg->yy_lp = 0; + /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; @@ -2080,6 +2207,9 @@ int yylex_destroy (yyscan_t yyscanner) yyfree(yyg->yy_start_stack ,yyscanner ); yyg->yy_start_stack = NULL; + yyfree ( yyg->yy_state_buf , yyscanner); + yyg->yy_state_buf = NULL; + /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( yyscanner); @@ -2138,7 +2268,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index 19f490f6ef8..b8ba48a1e52 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -222,6 +222,7 @@ void yyfree (void * ,yyscan_t yyscanner ); #ifdef YY_HEADER_EXPORT_START_CONDITIONS #define INITIAL 0 #define RAW 1 +#define NORMAL 2 #endif @@ -335,9 +336,9 @@ extern int yylex \ #undef YY_DECL #endif -#line 117 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 342 "sapi/phpdbg/phpdbg_lexer.h" +#line 343 "sapi/phpdbg/phpdbg_lexer.h" #undef yyIN_HEADER #endif /* yyHEADER_H */ diff --git a/phpdbg_lexer.l b/phpdbg_lexer.l index 79dd35e7cd5..ad5edd9f8f9 100644 --- a/phpdbg_lexer.l +++ b/phpdbg_lexer.l @@ -13,6 +13,7 @@ %} %s RAW +%s NORMAL %option outfile="sapi/phpdbg/phpdbg_lexer.c" header-file="sapi/phpdbg/phpdbg_lexer.h" %option warn nodefault @@ -41,16 +42,8 @@ ADDR 0x[a-fA-F0-9]+ OPCODE (ZEND_|zend_)([A-Za-z])+ INPUT [^\n]+ %% + { - {ID}[:]{1}[//]{2} { - phpdbg_init_param(yylval, STR_PARAM); - yylval->str = strndup(yytext, yyleng); - yylval->len = yyleng; - return T_PROTO; - } - [#]{1} { return T_POUND; } - [:]{2} { return T_DCOLON; } - [:]{1} { return T_COLON; } {T_EVAL} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -61,16 +54,37 @@ INPUT [^\n]+ phpdbg_init_param(yylval, EMPTY_PARAM); return T_SHELL; } - {T_IF} { - BEGIN(RAW); - phpdbg_init_param(yylval, EMPTY_PARAM); - return T_IF; - } {T_RUN}|{T_RUN_SHORT} { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); return T_RUN; } + + .+ { + BEGIN(NORMAL); + REJECT; + } +} + +{ + {T_IF} { + BEGIN(RAW); + phpdbg_init_param(yylval, EMPTY_PARAM); + return T_IF; + } +} + +{ + {ID}[:]{1}[//]{2} { + phpdbg_init_param(yylval, STR_PARAM); + yylval->str = strndup(yytext, yyleng); + yylval->len = yyleng; + return T_PROTO; + } + [#]{1} { return T_POUND; } + [:]{2} { return T_DCOLON; } + [:]{1} { return T_COLON; } + {T_YES}|{T_ON}|{T_ENABLED}|{T_TRUE} { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; diff --git a/phpdbg_parser.y b/phpdbg_parser.y index b1b2423fb1f..be37781cd1b 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -152,6 +152,10 @@ parameter $$.str = $2.str; $$.len = $2.len; } + | T_RUN { + $$.type = RUN_PARAM; + $$.len = 0; + } | T_OPCODE { $$ = $1; } | T_ADDR { $$ = $1; } | T_LITERAL { $$ = $1; } From a0ee96289b7e9a06e9dbb66f40258fc09b55cde2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 16 Apr 2014 20:55:41 +0200 Subject: [PATCH 124/137] Commented out a few PHPDBG_IS_QUITTING checks to fix bug If it does not work, please revert... --- phpdbg_prompt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index da06c71aff1..0077386bb91 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -265,13 +265,13 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ if (yyparse(&stack, scanner) <= 0) { switch (phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { +// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { phpdbg_error( "Unrecognized command in %s:%d: %s, %s!", init_file, line, input, why); } - } +// } break; } } @@ -1046,13 +1046,13 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ if (yyparse(&stack, scanner) <= 0) { switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { +// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { if (why) { phpdbg_error("%s", why); } } - } +// } if (why) { free(why); @@ -1254,7 +1254,7 @@ zend_vm_enter: ); \ } \ \ - do { \ +/* do { */\ switch (phpdbg_interactive(TSRMLS_C)) { \ case PHPDBG_LEAVE: \ case PHPDBG_FINISH: \ @@ -1263,7 +1263,7 @@ zend_vm_enter: goto next; \ } \ } \ - } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); \ +/* } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); */\ } while (0) /* allow conditional breakpoints and From 11c707d83657f2fd8347496d0959b27bdd454836 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 19 Apr 2014 21:08:54 +0100 Subject: [PATCH 125/137] auto compile when execution context set --- phpdbg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpdbg.c b/phpdbg.c index 213906a977b..2c5b7960d5e 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -929,7 +929,6 @@ phpdbg_main: step = 0; sapi_name = NULL; - while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (opt) { case 'r': @@ -1255,6 +1254,10 @@ phpdbg_main: phpdbg_welcome((cleaning > 0) TSRMLS_CC); } + if (PHPDBG_G(exec)) { + PHPDBG_COMMAND_HANDLER(compile)(NULL TSRMLS_CC); + } + /* initialize from file */ PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { From fd74024a4940fd8fc10daf9181beebc44c21ca32 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sat, 19 Apr 2014 21:22:09 +0100 Subject: [PATCH 126/137] remove compile command --- phpdbg.c | 3 +- phpdbg_help.c | 18 +-- phpdbg_lexer.c | 289 ++++++++++++++++++++++++------------------------ phpdbg_lexer.h | 16 ++- phpdbg_prompt.c | 26 +---- 5 files changed, 162 insertions(+), 190 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index bf6dbd4e1f1..8fde93cd909 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -1260,8 +1260,9 @@ phpdbg_main: phpdbg_welcome((cleaning > 0) TSRMLS_CC); } + /* auto compile */ if (PHPDBG_G(exec)) { - PHPDBG_COMMAND_HANDLER(compile)(NULL TSRMLS_CC); + phpdbg_compile(TSRMLS_C); } /* initialize from file */ diff --git a/phpdbg_help.c b/phpdbg_help.c index 250fb132d2b..331c28fdb28 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -322,9 +322,6 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **print** print argument " CR " **frame** select a stack frame and print a stack frame summary" CR CR -"**Compilation**" CR -" **compile** compile a PHP source" CR CR - "**Starting and Stopping Execution**" CR " **exec** set execution context" CR " **run** attempt execution" CR @@ -580,19 +577,6 @@ phpdbg_help_text_t phpdbg_help_text[] = { "Note: if all breakpoints are cleared, then the PHP script will run until normal completion." }, -{"compile", -"The execution context may be pre-compiled before execution to provide an opportunity to " -"inspect the generated opcode output. The execution context must be defined before the compile " -"command can be used. Use the command **exec** to set the execution context." CR CR - -"**Examples**" CR CR -" $P compile" CR -" $P c" CR CR - -"Note: Then that it is usually necessary to issue a **clean** command to reset the environment prior " -"to compilation." -}, - {"ev", "The **ev** command takes a string expression which it evaluates and then displays. It " "evaluates in the context of the lowest (that is the executing) frame, unless this has first " @@ -615,7 +599,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { {"exec", "The **exec** command sets the execution context, that is the script to be executed. The " "execution context must be defined either by executing the **exec** command or by using the " -"**-e** command line option before the script can be compiled or run." CR CR +"**-e** command line option." CR CR "Note that the **exec** command also can be used to replace a previously defined execution " "context." CR CR diff --git a/phpdbg_lexer.c b/phpdbg_lexer.c index f3244905a1f..c289004b981 100644 --- a/phpdbg_lexer.c +++ b/phpdbg_lexer.c @@ -9,7 +9,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -47,7 +47,6 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -55,7 +54,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -86,6 +84,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -326,7 +326,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap(yyscanner) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; @@ -345,7 +345,7 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ - yyleng = (yy_size_t) (yy_cp - yy_bp); \ + yyleng = (size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; @@ -359,7 +359,7 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_acclist[231] = +static yyconst flex_int16_t yy_acclist[229] = { 0, 19, 4, 15, 18, 4, 17, 18, 17, 18, 4, 7, 18, 4, 12, 15, 18, 4, 12, 15, 18, @@ -380,15 +380,15 @@ static yyconst flex_int16_t yy_acclist[231] = 5, 15, 11, 15, 15, 10, 15, 15, 15, 15, 4, 4, 13, 15, 4, 15, 4, 15, 4, 15, 4, 15, 3, 4, 15, 4, 15, 4, 15, 13, - 15, 15, 15, 15, 15, 15, 15, 4, 4, 15, - 4, 15, 4, 15, 4, 15, 4, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 4, 6, 4, + 15, 4, 15, 4, 15, 4, 15, 4, 15, 6, - 15, 15, 15, 4, 4, 15, 4, 15, 4, 15, - 15, 15, 15, 4, 6, 4, 14, 15, 4, 15, - 4, 15, 6, 14, 15, 15, 15, 4, 15, 15 + 15, 15, 15, 15, 15, 4, 15, 4, 15, 4, + 15, 15, 15, 15, 4, 14, 15, 4, 15, 4, + 15, 14, 15, 15, 15, 4, 15, 15 } ; -static yyconst flex_int16_t yy_accept[131] = +static yyconst flex_int16_t yy_accept[127] = { 0, 1, 1, 1, 1, 1, 1, 1, 2, 5, 8, 10, 13, 17, 21, 24, 27, 30, 33, 36, 39, @@ -399,11 +399,11 @@ static yyconst flex_int16_t yy_accept[131] = 133, 135, 137, 139, 140, 142, 143, 143, 145, 146, 147, 148, 149, 150, 151, 153, 155, 156, 158, 159, 160, 161, 162, 165, 167, 169, 171, 173, 176, 178, - 180, 180, 182, 183, 184, 185, 186, 187, 188, 189, + 180, 180, 182, 183, 184, 185, 186, 187, 188, 190, - 191, 193, 195, 197, 199, 199, 200, 201, 202, 203, - 204, 205, 207, 209, 211, 211, 212, 213, 214, 216, - 219, 221, 223, 224, 226, 227, 228, 230, 231, 231 + 192, 194, 196, 198, 200, 201, 202, 203, 204, 205, + 206, 208, 210, 212, 213, 214, 215, 218, 220, 222, + 224, 225, 226, 228, 229, 229 } ; static yyconst flex_int32_t yy_ec[256] = @@ -440,51 +440,51 @@ static yyconst flex_int32_t yy_ec[256] = static yyconst flex_int32_t yy_meta[35] = { 0, - 1, 2, 3, 2, 1, 1, 1, 1, 4, 1, + 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[139] = +static yyconst flex_int16_t yy_base[133] = { 0, - 0, 0, 33, 35, 38, 0, 385, 71, 74, 76, - 378, 79, 87, 90, 96, 100, 108, 109, 112, 120, - 123, 126, 138, 142, 148, 0, 104, 356, 479, 151, - 162, 351, 73, 92, 65, 146, 122, 94, 152, 127, - 155, 163, 172, 354, 131, 176, 182, 324, 190, 319, + 0, 0, 33, 35, 38, 0, 357, 71, 74, 76, + 352, 79, 87, 90, 96, 100, 108, 109, 112, 120, + 123, 126, 138, 142, 148, 0, 104, 316, 455, 151, + 162, 313, 73, 92, 65, 146, 122, 94, 152, 127, + 155, 163, 172, 318, 131, 176, 182, 288, 190, 314, 178, 184, 187, 211, 212, 215, 221, 224, 225, 235, - 236, 239, 245, 0, 203, 260, 259, 248, 264, 479, + 236, 239, 245, 0, 203, 260, 259, 248, 264, 455, 237, 190, 243, 253, 255, 222, 259, 194, 249, 250, - 277, 285, 0, 286, 289, 299, 303, 307, 316, 319, - 0, 0, 252, 283, 295, 287, 290, 305, 325, 328, + 277, 229, 0, 285, 286, 289, 295, 304, 307, 310, + 184, 0, 252, 283, 292, 296, 306, 309, 163, 328, - 331, 337, 343, 346, 181, 310, 333, 334, 344, 350, - 229, 366, 374, 375, 160, 398, 345, 371, 146, 414, - 388, 392, 479, 430, 380, 393, 423, 415, 479, 446, - 450, 454, 458, 462, 466, 96, 470, 474 + 329, 332, 341, 344, 455, 326, 331, 330, 342, 343, + 362, 370, 371, 394, 368, 356, 410, 384, 404, 426, + 376, 378, 420, 411, 455, 442, 445, 447, 450, 148, + 452, 96 } ; -static yyconst flex_int16_t yy_def[139] = +static yyconst flex_int16_t yy_def[133] = { 0, - 129, 1, 130, 130, 129, 5, 129, 131, 132, 129, - 132, 131, 131, 132, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 133, 133, 134, 129, 134, - 134, 129, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 131, 132, 132, 132, 129, 13, 13, 132, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 133, 133, 134, 129, 134, 134, 129, - 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 135, 49, 131, 131, 131, 131, 131, 131, 131, - 136, 69, 134, 134, 134, 134, 134, 134, 135, 131, + 125, 1, 126, 126, 125, 5, 125, 127, 128, 125, + 128, 127, 127, 128, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 129, 129, 130, 125, 130, + 130, 125, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 127, 128, 128, 128, 125, 13, 13, 128, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 129, 129, 130, 125, 130, 130, 125, + 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, + 130, 128, 49, 127, 127, 127, 127, 127, 127, 127, + 125, 69, 130, 130, 130, 130, 130, 130, 128, 127, - 131, 131, 131, 131, 136, 134, 134, 134, 134, 134, - 132, 137, 131, 131, 129, 138, 134, 134, 132, 137, - 131, 131, 129, 138, 134, 134, 131, 134, 0, 129, - 129, 129, 129, 129, 129, 129, 129, 129 + 127, 127, 127, 127, 125, 130, 130, 130, 130, 130, + 131, 127, 127, 132, 130, 130, 131, 127, 127, 132, + 130, 130, 127, 130, 0, 125, 125, 125, 125, 125, + 125, 125 } ; -static yyconst flex_int16_t yy_nxt[514] = +static yyconst flex_int16_t yy_nxt[490] = { 0, 8, 9, 10, 11, 12, 8, 13, 12, 14, 8, 8, 8, 8, 8, 15, 8, 8, 8, 16, 17, @@ -495,57 +495,53 @@ static yyconst flex_int16_t yy_nxt[514] = 37, 28, 38, 39, 28, 28, 40, 28, 28, 28, 41, 42, 44, 67, 44, 46, 47, 47, 47, 45, 44, 67, 44, 48, 71, 48, 48, 45, 44, 73, - 44, 48, 129, 48, 48, 45, 105, 44, 50, 44, + 44, 48, 125, 48, 48, 45, 120, 44, 50, 44, 67, 44, 67, 44, 45, 65, 47, 51, 45, 44, 44, 44, 44, 44, 72, 44, 45, 45, 49, 76, 45, 44, 52, 44, 44, 55, 44, 44, 45, 44, - 67, 45, 53, 129, 45, 67, 82, 56, 54, 44, - 57, 44, 75, 44, 58, 44, 45, 60, 129, 44, + 67, 45, 53, 125, 45, 67, 82, 56, 54, 44, + 57, 44, 75, 44, 58, 44, 45, 60, 66, 44, 45, 44, 59, 79, 67, 68, 45, 68, 68, 67, - 67, 62, 74, 67, 61, 123, 68, 63, 68, 68, + 67, 62, 74, 67, 61, 125, 68, 63, 68, 68, 67, 67, 77, 44, 80, 44, 78, 46, 47, 44, - 45, 44, 81, 47, 47, 44, 45, 44, 44, 115, + 45, 44, 81, 47, 47, 44, 45, 44, 44, 105, 44, 84, 45, 69, 43, 45, 83, 83, 67, 83, 83, 83, 67, 86, 65, 47, 83, 83, 83, 83, 83, 85, 44, 44, 44, 44, 44, 94, 44, 45, 45, 43, 44, 45, 44, 44, 44, 44, 44, 45, - 67, 129, 45, 45, 119, 87, 44, 44, 44, 44, + 67, 125, 45, 45, 99, 87, 44, 44, 44, 44, 44, 56, 44, 45, 45, 67, 44, 45, 44, 88, 93, 67, 68, 45, 68, 68, 67, 67, 67, 95, 67, 67, 106, 67, 91, 89, 58, 67, 67, 90, 92, 92, 67, 92, 92, 92, 96, 78, 97, 76, 92, 92, 92, 92, 92, 67, 44, 44, 44, 44, - 44, 67, 44, 44, 45, 67, 100, 45, 67, 107, + 44, 67, 44, 45, 45, 100, 44, 45, 44, 107, - 44, 98, 44, 67, 44, 101, 44, 45, 44, 78, - 44, 45, 108, 67, 109, 45, 102, 44, 67, 44, - 44, 129, 44, 110, 45, 116, 44, 45, 44, 44, - 103, 44, 44, 111, 44, 58, 45, 104, 44, 45, - 44, 67, 67, 112, 44, 45, 44, 44, 113, 44, - 117, 45, 67, 67, 45, 43, 129, 118, 67, 70, - 114, 112, 56, 76, 67, 116, 43, 44, 125, 44, - 43, 43, 43, 43, 45, 44, 44, 44, 44, 67, - 129, 43, 45, 45, 129, 129, 129, 129, 67, 44, - 126, 44, 129, 44, 122, 44, 45, 121, 66, 128, + 67, 98, 101, 45, 67, 44, 102, 44, 44, 108, + 44, 44, 45, 44, 67, 45, 125, 67, 45, 43, + 125, 70, 103, 109, 67, 78, 58, 110, 104, 44, + 44, 44, 44, 44, 67, 44, 45, 45, 67, 67, + 45, 114, 44, 111, 44, 44, 112, 44, 115, 45, + 67, 67, 45, 116, 125, 113, 125, 125, 114, 111, + 56, 76, 43, 44, 67, 44, 43, 43, 43, 43, + 45, 44, 44, 44, 44, 122, 67, 43, 45, 45, + 125, 125, 125, 125, 67, 44, 67, 44, 125, 125, + 119, 121, 45, 118, 66, 124, 78, 125, 66, 66, - 45, 67, 66, 66, 66, 66, 67, 127, 129, 129, - 58, 78, 129, 66, 43, 44, 129, 44, 43, 43, - 43, 43, 45, 67, 44, 129, 44, 129, 129, 43, - 66, 45, 129, 76, 66, 66, 66, 66, 67, 129, - 129, 56, 129, 129, 129, 66, 26, 26, 26, 26, - 43, 43, 129, 43, 44, 44, 44, 44, 64, 64, - 129, 64, 66, 129, 129, 66, 99, 99, 129, 99, - 120, 120, 129, 120, 124, 129, 129, 124, 7, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129 + 66, 66, 67, 123, 125, 44, 125, 44, 125, 66, + 43, 44, 45, 44, 43, 43, 43, 43, 45, 67, + 125, 44, 58, 44, 125, 43, 66, 125, 45, 76, + 66, 66, 66, 66, 67, 125, 125, 125, 56, 125, + 125, 66, 26, 26, 26, 43, 43, 44, 44, 44, + 64, 64, 117, 117, 7, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125 } ; -static yyconst flex_int16_t yy_chk[514] = +static yyconst flex_int16_t yy_chk[490] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -556,54 +552,50 @@ static yyconst flex_int16_t yy_chk[514] = 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 35, 8, 9, 9, 10, 10, 8, 12, 33, 12, 12, 33, 12, 12, 12, 13, 35, - 13, 13, 14, 13, 13, 13, 136, 15, 14, 15, + 13, 13, 14, 13, 13, 13, 132, 15, 14, 15, 34, 16, 38, 16, 15, 27, 27, 15, 16, 17, 18, 17, 18, 19, 34, 19, 17, 18, 13, 38, 19, 20, 16, 20, 21, 18, 21, 22, 20, 22, 37, 21, 17, 45, 22, 40, 45, 19, 17, 23, - 20, 23, 37, 24, 20, 24, 23, 22, 119, 25, + 20, 23, 37, 24, 20, 24, 23, 22, 130, 25, 24, 25, 21, 40, 36, 30, 25, 30, 30, 30, - 39, 24, 36, 41, 23, 115, 31, 25, 31, 31, + 39, 24, 36, 41, 23, 99, 31, 25, 31, 31, 31, 42, 39, 43, 41, 43, 39, 46, 46, 51, - 43, 51, 42, 47, 47, 52, 51, 52, 53, 105, + 43, 51, 42, 47, 47, 52, 51, 52, 53, 91, 53, 51, 52, 31, 49, 53, 49, 49, 72, 49, 49, 49, 78, 53, 65, 65, 49, 49, 49, 49, 49, 52, 54, 55, 54, 55, 56, 72, 56, 54, 55, 49, 57, 56, 57, 58, 59, 58, 59, 57, - 76, 111, 58, 59, 111, 55, 60, 61, 60, 61, + 76, 82, 58, 59, 82, 55, 60, 61, 60, 61, 62, 57, 62, 60, 61, 71, 63, 62, 63, 59, 71, 73, 68, 63, 68, 68, 68, 79, 80, 73, 93, 74, 93, 75, 67, 61, 62, 77, 66, 63, 69, 69, 69, 69, 69, 69, 74, 80, 79, 77, - 69, 69, 69, 69, 69, 81, 82, 84, 82, 84, - 85, 94, 85, 82, 84, 96, 84, 85, 97, 94, + 69, 69, 69, 69, 69, 81, 84, 85, 84, 85, + 86, 94, 86, 84, 85, 84, 87, 86, 87, 94, - 86, 81, 86, 95, 87, 85, 87, 86, 88, 97, - 88, 87, 95, 98, 96, 88, 86, 89, 106, 89, - 90, 50, 90, 98, 89, 106, 99, 90, 99, 100, - 87, 100, 101, 99, 101, 89, 100, 90, 102, 101, - 102, 107, 108, 100, 103, 102, 103, 104, 101, 104, - 107, 103, 109, 117, 104, 48, 44, 108, 110, 32, - 102, 104, 103, 109, 28, 110, 112, 112, 117, 112, - 112, 112, 112, 112, 112, 113, 114, 113, 114, 118, - 11, 112, 113, 114, 7, 0, 0, 0, 125, 121, - 118, 121, 0, 122, 114, 122, 121, 113, 116, 125, + 95, 81, 85, 87, 96, 88, 86, 88, 89, 95, + 89, 90, 88, 90, 97, 89, 50, 98, 90, 48, + 44, 32, 87, 96, 28, 97, 89, 98, 90, 100, + 101, 100, 101, 102, 106, 102, 100, 101, 108, 107, + 102, 106, 103, 100, 103, 104, 101, 104, 107, 103, + 109, 110, 104, 108, 11, 102, 7, 0, 110, 104, + 103, 109, 111, 111, 116, 111, 111, 111, 111, 111, + 111, 112, 113, 112, 113, 116, 115, 111, 112, 113, + 0, 0, 0, 0, 121, 118, 122, 118, 0, 0, + 113, 115, 118, 112, 114, 121, 122, 0, 114, 114, - 122, 126, 116, 116, 116, 116, 116, 121, 0, 0, - 122, 126, 0, 116, 120, 120, 0, 120, 120, 120, - 120, 120, 120, 128, 127, 0, 127, 0, 0, 120, - 124, 127, 0, 128, 124, 124, 124, 124, 124, 0, - 0, 127, 0, 0, 0, 124, 130, 130, 130, 130, - 131, 131, 0, 131, 132, 132, 132, 132, 133, 133, - 0, 133, 134, 0, 0, 134, 135, 135, 0, 135, - 137, 137, 0, 137, 138, 0, 0, 138, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129 + 114, 114, 114, 118, 0, 119, 0, 119, 0, 114, + 117, 117, 119, 117, 117, 117, 117, 117, 117, 124, + 0, 123, 119, 123, 0, 117, 120, 0, 123, 124, + 120, 120, 120, 120, 120, 0, 0, 0, 123, 0, + 0, 120, 126, 126, 126, 127, 127, 128, 128, 128, + 129, 129, 131, 131, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125 } ; #define REJECT \ @@ -617,8 +609,8 @@ goto find_rule; \ #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET -#line 1 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 2 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 1 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 2 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" /* * phpdbg_lexer.l @@ -633,7 +625,7 @@ goto find_rule; \ #define YY_NO_UNISTD_H 1 -#line 637 "sapi/phpdbg/phpdbg_lexer.c" +#line 629 "sapi/phpdbg/phpdbg_lexer.c" #define INITIAL 0 #define RAW 1 @@ -737,6 +729,10 @@ int yyget_lineno (yyscan_t yyscanner ); void yyset_lineno (int line_number ,yyscan_t yyscanner ); +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + YYSTYPE * yyget_lval (yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -783,7 +779,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -794,7 +790,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - yy_size_t n; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -879,10 +875,10 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 44 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 44 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 886 "sapi/phpdbg/phpdbg_lexer.c" +#line 882 "sapi/phpdbg/phpdbg_lexer.c" yylval = yylval_param; @@ -942,19 +938,18 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 130 ) + if ( yy_current_state >= 126 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *yyg->yy_state_ptr++ = yy_current_state; ++yy_cp; } - while ( yy_current_state != 129 ); + while ( yy_current_state != 125 ); yy_find_action: yy_current_state = *--yyg->yy_state_ptr; yyg->yy_lp = yy_accept[yy_current_state]; -goto find_rule; /* Shut up GCC warning -Wall */ find_rule: /* we branch to this label when backing up */ for ( ; ; ) /* until we find what rule we matched */ { @@ -980,7 +975,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 47 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 47 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -989,7 +984,7 @@ YY_RULE_SETUP YY_BREAK case 2: YY_RULE_SETUP -#line 52 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 52 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -998,7 +993,7 @@ YY_RULE_SETUP YY_BREAK case 3: YY_RULE_SETUP -#line 57 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 57 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -1007,7 +1002,7 @@ YY_RULE_SETUP YY_BREAK case 4: YY_RULE_SETUP -#line 63 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 63 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(NORMAL); REJECT; @@ -1017,7 +1012,7 @@ YY_RULE_SETUP case 5: YY_RULE_SETUP -#line 70 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 70 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { BEGIN(RAW); phpdbg_init_param(yylval, EMPTY_PARAM); @@ -1028,7 +1023,7 @@ YY_RULE_SETUP case 6: YY_RULE_SETUP -#line 78 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 78 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1038,22 +1033,22 @@ YY_RULE_SETUP YY_BREAK case 7: YY_RULE_SETUP -#line 84 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 84 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_POUND; } YY_BREAK case 8: YY_RULE_SETUP -#line 85 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 85 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_DCOLON; } YY_BREAK case 9: YY_RULE_SETUP -#line 86 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 86 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { return T_COLON; } YY_BREAK case 10: YY_RULE_SETUP -#line 88 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 88 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 1; @@ -1062,7 +1057,7 @@ YY_RULE_SETUP YY_BREAK case 11: YY_RULE_SETUP -#line 93 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 93 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = 0; @@ -1071,7 +1066,7 @@ YY_RULE_SETUP YY_BREAK case 12: YY_RULE_SETUP -#line 98 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 98 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, NUMERIC_PARAM); yylval->num = atoi(yytext); @@ -1080,7 +1075,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 103 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 103 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, ADDR_PARAM); yylval->addr = strtoul(yytext, 0, 16); @@ -1089,7 +1084,7 @@ YY_RULE_SETUP YY_BREAK case 14: YY_RULE_SETUP -#line 108 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 108 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, OP_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1099,7 +1094,7 @@ YY_RULE_SETUP YY_BREAK case 15: YY_RULE_SETUP -#line 114 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 114 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1110,7 +1105,7 @@ YY_RULE_SETUP case 16: YY_RULE_SETUP -#line 122 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 122 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { phpdbg_init_param(yylval, STR_PARAM); yylval->str = strndup(yytext, yyleng); @@ -1122,15 +1117,15 @@ YY_RULE_SETUP case 17: /* rule 17 can match eol */ YY_RULE_SETUP -#line 130 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 130 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" { /* ignore whitespace */ } YY_BREAK case 18: YY_RULE_SETUP -#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1134 "sapi/phpdbg/phpdbg_lexer.c" +#line 1129 "sapi/phpdbg/phpdbg_lexer.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(RAW): case YY_STATE_EOF(NORMAL): @@ -1395,7 +1390,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 130 ) + if ( yy_current_state >= 126 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1419,14 +1414,15 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 130 ) + if ( yy_current_state >= 126 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 129); + yy_is_jam = (yy_current_state == 125); if ( ! yy_is_jam ) *yyg->yy_state_ptr++ = yy_current_state; + (void)yyg; return yy_is_jam ? 0 : yy_current_state; } @@ -1517,7 +1513,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) case EOB_ACT_END_OF_FILE: { if ( yywrap(yyscanner ) ) - return 0; + return EOF; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; @@ -1866,8 +1862,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ @@ -1875,7 +1871,8 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n, i; + yy_size_t n; + yy_size_t i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2021,7 +2018,7 @@ void yyset_lineno (int line_number , yyscan_t yyscanner) /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_lineno called with no buffer" ); yylineno = line_number; } @@ -2036,7 +2033,7 @@ void yyset_column (int column_no , yyscan_t yyscanner) /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_column called with no buffer" , yyscanner); + YY_FATAL_ERROR( "yyset_column called with no buffer" ); yycolumn = column_no; } @@ -2268,7 +2265,7 @@ void yyfree (void * ptr , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" diff --git a/phpdbg_lexer.h b/phpdbg_lexer.h index b8ba48a1e52..1958cef9a26 100644 --- a/phpdbg_lexer.h +++ b/phpdbg_lexer.h @@ -13,7 +13,7 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 +#define YY_FLEX_SUBMINOR_VERSION 37 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -51,7 +51,6 @@ typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; @@ -59,7 +58,6 @@ typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -90,6 +88,8 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif +#endif /* ! C99 */ + #endif /* ! FLEXINT_H */ #ifdef __cplusplus @@ -214,7 +214,7 @@ void yyfree (void * ,yyscan_t yyscanner ); /* Begin user sect3 */ -#define yywrap(n) 1 +#define yywrap(yyscanner) 1 #define YY_SKIP_YYWRAP #define yytext_ptr yytext_r @@ -271,6 +271,10 @@ int yyget_lineno (yyscan_t yyscanner ); void yyset_lineno (int line_number ,yyscan_t yyscanner ); +int yyget_column (yyscan_t yyscanner ); + +void yyset_column (int column_no ,yyscan_t yyscanner ); + YYSTYPE * yyget_lval (yyscan_t yyscanner ); void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); @@ -336,9 +340,9 @@ extern int yylex \ #undef YY_DECL #endif -#line 131 "/var/root/php-src/sapi/phpdbg/phpdbg_lexer.l" +#line 131 "/usr/src/php-src/sapi/phpdbg/phpdbg_lexer.l" -#line 343 "sapi/phpdbg/phpdbg_lexer.h" +#line 347 "sapi/phpdbg/phpdbg_lexer.h" #undef yyIN_HEADER #endif /* yyHEADER_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 0077386bb91..c3971ccef4b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -43,7 +43,6 @@ int yyparse(phpdbg_param_t *stack, yyscan_t scanner); /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"), - PHPDBG_COMMAND_D(compile, "attempt compilation", 'c', NULL, 0), PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), @@ -376,6 +375,7 @@ PHPDBG_COMMAND(exec) /* {{{ */ php_hash_environment(TSRMLS_C); phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); + phpdbg_compile(TSRMLS_C); } else { phpdbg_notice("Execution context not changed"); } @@ -392,6 +392,11 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ { zend_file_handle fh; + if (!PHPDBG_G(exec)) { + phpdbg_error("No execution context"); + return SUCCESS; + } + if (EG(in_execution)) { phpdbg_error("Cannot compile while in execution"); return FAILURE; @@ -414,25 +419,6 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ return FAILURE; } /* }}} */ -PHPDBG_COMMAND(compile) /* {{{ */ -{ - if (!PHPDBG_G(exec)) { - phpdbg_error("No execution context"); - return SUCCESS; - } - - if (!EG(in_execution)) { - if (PHPDBG_G(ops)) { - phpdbg_error("Destroying previously compiled opcodes"); - phpdbg_clean(0 TSRMLS_CC); - } - } - - phpdbg_compile(TSRMLS_C); - - return SUCCESS; -} /* }}} */ - PHPDBG_COMMAND(step) /* {{{ */ { if (param->num) { From 508c379428f2d1bc14321fdada9170bb15b8776e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 20 Apr 2014 12:54:50 +0200 Subject: [PATCH 127/137] Added error on compile failure in exec cmd --- phpdbg_prompt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c3971ccef4b..c6297c02073 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -375,7 +375,10 @@ PHPDBG_COMMAND(exec) /* {{{ */ php_hash_environment(TSRMLS_C); phpdbg_notice("Set execution context: %s", PHPDBG_G(exec)); - phpdbg_compile(TSRMLS_C); + + if (phpdbg_compile(TSRMLS_C) == FAILURE) { + phpdbg_error("Failed to compile %s", PHPDBG_G(exec)); + } } else { phpdbg_notice("Execution context not changed"); } From 5a7497904e4f0f3bd300e1353a26fab80c178321 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 20 Apr 2014 13:25:28 +0200 Subject: [PATCH 128/137] Breakpoints now hit only once if line was not switched --- phpdbg.h | 1 + phpdbg_prompt.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index 43f26ca3236..615af577f1c 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -173,6 +173,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ + zend_uint last_line; /* last executed line */ #ifndef _WIN32 struct sigaction old_sigsegv_signal; /* segv signal handler */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c6297c02073..dcbd2ba3273 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1325,10 +1325,10 @@ zend_vm_enter: { phpdbg_breakbase_t *brake; - if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) && - (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC))) { - phpdbg_hit_breakpoint( - brake, 1 TSRMLS_CC); + if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) + && (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC)) + && (brake->type != PHPDBG_BREAK_FILE || execute_data->opline->lineno != PHPDBG_G(last_line))) { + phpdbg_hit_breakpoint(brake, 1 TSRMLS_CC); DO_INTERACTIVE(); } } @@ -1345,6 +1345,8 @@ next: DO_INTERACTIVE(); } + PHPDBG_G(last_line) = execute_data->opline->lineno; + PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); if (PHPDBG_G(vmret) > 0) { From d21d5c98a53ddedc3e15d53f8dbe5d71eb06417e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 20 Apr 2014 13:28:11 +0200 Subject: [PATCH 129/137] Fixed potential bug in run command --- phpdbg_parser.y | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpdbg_parser.y b/phpdbg_parser.y index be37781cd1b..4a84504e2e5 100644 --- a/phpdbg_parser.y +++ b/phpdbg_parser.y @@ -147,15 +147,15 @@ parameter $$.str = $2.str; $$.len = $2.len; } + | T_RUN { + $$.type = RUN_PARAM; + $$.len = 0; + } | T_RUN T_INPUT { $$.type = RUN_PARAM; $$.str = $2.str; $$.len = $2.len; } - | T_RUN { - $$.type = RUN_PARAM; - $$.len = 0; - } | T_OPCODE { $$ = $1; } | T_ADDR { $$ = $1; } | T_LITERAL { $$ = $1; } From e097919f160391c23d93d3ad9a94a505d7c230d8 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 20 Apr 2014 16:47:24 +0200 Subject: [PATCH 130/137] Stepping is now line by line with gdb style command --- phpdbg_prompt.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index dcbd2ba3273..6eb7481c5ec 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -43,7 +43,7 @@ int yyparse(phpdbg_param_t *stack, yyscan_t scanner); /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"), - PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), + PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0), PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), @@ -424,16 +424,9 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ PHPDBG_COMMAND(step) /* {{{ */ { - if (param->num) { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - } else { - PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; - } + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; - phpdbg_notice("Stepping %s", - (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); - - return SUCCESS; + return PHPDBG_NEXT; } /* }}} */ PHPDBG_COMMAND(next) /* {{{ */ @@ -1314,6 +1307,11 @@ zend_vm_enter: phpdbg_print_opline_ex( execute_data, &vars, 0 TSRMLS_CC); + if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING && execute_data->opline->lineno != PHPDBG_G(last_line)) { + PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; + DO_INTERACTIVE(); + } + /* check if some watchpoint was hit */ { if (phpdbg_print_changed_zvals(TSRMLS_C) == SUCCESS) { @@ -1333,10 +1331,6 @@ zend_vm_enter: } } - if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) { - DO_INTERACTIVE(); - } - next: if (PHPDBG_G(flags) & PHPDBG_IS_SIGNALED) { phpdbg_writeln(EMPTY); From 56293fc0dd288f1c1a68880b6055f2eca8dad0e2 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 20 Apr 2014 16:55:49 +0200 Subject: [PATCH 131/137] Update help --- phpdbg_help.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 331c28fdb28..a00f445638b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -325,7 +325,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { "**Starting and Stopping Execution**" CR " **exec** set execution context" CR " **run** attempt execution" CR -" **step** Enable or disable per opcode stepping mode" CR +" **step** continue execution until other line is reached" CR " **next** continue execution" CR " **until** continue execution up to the given location" CR " **finish** continue up to end of the current execution frame" CR @@ -861,20 +861,12 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, {"step", -"You can enable and disable **stepping** mode at the phpdbg prompt during execution. When " -"stepping mode is enabled, execution will be step through opcode by opcode." CR CR +"Execute opcodes until beginning on next line" CR CR "**Examples**" CR CR -" $P step 1" CR -" $P s 1" CR -" Will enable stepping" CR CR -"While stepping is enabled you are presented with an interactive prompt after the execution of " -"each opcode." CR CR - -"Note that when executing the **finish** and **leave** commands, and oplines within the current " -"execution frame will be skipped in line with the command behaviour. Stepping will resume on exit " -"from the current frame." +" $P s" CR +" Will continue and break again in the next encountered line" CR CR }, {"until", From 373b9ecd05e5c88fd224e9a081680e1109dbb4ed Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 20 Apr 2014 17:10:52 +0100 Subject: [PATCH 132/137] rename next to continue, cleanup help --- phpdbg_help.c | 20 +++++++++----------- phpdbg_prompt.c | 4 ++-- phpdbg_prompt.h | 3 +-- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 331c28fdb28..4866f1e67e2 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -318,30 +318,28 @@ phpdbg_help_text_t phpdbg_help_text[] = { "**Information**" CR " **list** list PHP source" CR " **info** displays information on the debug session" CR -" **help** provide help on a topic" CR -" **print** print argument " CR -" **frame** select a stack frame and print a stack frame summary" CR CR +" **print** show opcodes " CR +" **frame** select a stack frame and print a stack frame summary" CR +" **help** provide help on a topic" CR CR "**Starting and Stopping Execution**" CR " **exec** set execution context" CR " **run** attempt execution" CR -" **step** Enable or disable per opcode stepping mode" CR -" **next** continue execution" CR +" **continue** continue execution" CR " **until** continue execution up to the given location" CR " **finish** continue up to end of the current execution frame" CR " **leave** continue up to end of the current execution frame and halt after the calling instruction" CR " **break** set a breakpoint at the specified target" CR " **watch** set a watchpoint on $variable" CR -" **ev** evaluate some code" CR " **clear** clear one or all breakpoints" CR " **clean** clean the execution environment" CR CR "**Miscellaneous**" CR -" **quiet** silence some output" CR " **set** set the phpdbg configuration" CR " **source** execute a phpdbginit script" CR " **register** register a phpdbginit function as a command alias" CR " **sh** shell a command" CR +" **ev** evaluate some code" CR " **quit** exit phpdbg" CR CR "Type **help ** or (**help alias**) to get detailed help on any of the above commands, " @@ -714,12 +712,12 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, //*********** what is the difference between n and s ??? -{"next", -"The **next** command causes control to be passed back to the vm, continuing execution. The next " -"opline will be executed if **step 1** is set. Otherwise execution will continue to the next " +{"continue", +"The **continue** command causes control to be passed back to the vm, continuing execution. The next " +"opline will be executed if **step** is set **on**. Otherwise execution will continue to the next " "breakpoint or script completion" CR CR -"Note **next** will trigger a \"not running\" error if not executing." +"Note **continue** will trigger a \"not running\" error if not executing." }, {"print", diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c3971ccef4b..1b1cb25215b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -44,7 +44,7 @@ int yyparse(phpdbg_param_t *stack, yyscan_t scanner); const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s"), PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, "b"), - PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0), + PHPDBG_COMMAND_D(continue,"continue execution", 'c', NULL, 0), PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s"), PHPDBG_COMMAND_D(ev, "evaluate some code", 0, NULL, "i"), PHPDBG_COMMAND_D(until, "continue past the current line", 'u', NULL, 0), @@ -433,7 +433,7 @@ PHPDBG_COMMAND(step) /* {{{ */ return SUCCESS; } /* }}} */ -PHPDBG_COMMAND(next) /* {{{ */ +PHPDBG_COMMAND(continue) /* {{{ */ { return PHPDBG_NEXT; } /* }}} */ diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 51efffa0d3f..ef648aabeb0 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -30,9 +30,8 @@ void phpdbg_clean(zend_bool full TSRMLS_DC); /* }}} */ /* {{{ phpdbg command handlers */ PHPDBG_COMMAND(exec); -PHPDBG_COMMAND(compile); PHPDBG_COMMAND(step); -PHPDBG_COMMAND(next); +PHPDBG_COMMAND(continue); PHPDBG_COMMAND(run); PHPDBG_COMMAND(ev); PHPDBG_COMMAND(until); From f96feea00c112bc1bec3e7b677218f4b487d1152 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Sun, 20 Apr 2014 18:46:35 +0100 Subject: [PATCH 133/137] step by line and opcode modes preserved, set stepping added, help updated --- phpdbg.h | 2 ++ phpdbg_help.c | 14 +++++++++----- phpdbg_prompt.c | 6 +++++- phpdbg_set.c | 30 ++++++++++++++++++++++++++++-- phpdbg_set.h | 1 + 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/phpdbg.h b/phpdbg.h index 43f26ca3236..c24c5ea1fe8 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -140,6 +140,7 @@ #define PHPDBG_IS_DISCONNECTED (1<<27) #define PHPDBG_SHOW_REFCOUNTS (1<<28) +#define PHPDBG_STEP_OPCODE (1<<29) #define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) #define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) @@ -200,6 +201,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) phpdbg_command_t *lcmd; /* last command */ phpdbg_param_t lparam; /* last param */ + zend_ulong lline; /* last line */ zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ diff --git a/phpdbg_help.c b/phpdbg_help.c index 4866f1e67e2..2a6f9e82b65 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -800,12 +800,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **Type** **Alias** **Purpose**" CR " **prompt** **p** set the prompt" CR " **color** **c** set color " CR -" **colors** **C** set colors " CR -" **oplog** **O** set oplog output" CR +" **colors** **C** set colors []" CR +" **oplog** **O** set oplog [output]" CR " **break** **b** set break **id** " CR -" **breaks** **B** set breaks " CR -" **quiet** **q** set quiet " CR -" **refcount** **r** set refcount (refcount display upon hit watchpoint)" CR CR +" **breaks** **B** set breaks []" CR +" **quiet** **q** set quiet []" CR +" **stepping** **s** set stepping []" CR +" **refcount** **r** set refcount [] " CR CR "Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, " "**cyan** and **black**. All colours except **none** can be followed by an optional " @@ -824,6 +825,9 @@ phpdbg_help_text_t phpdbg_help_text[] = { " $P S c error red-bold" CR " Use red bold for errors" CR CR +" $P S refcount on" CR +" Enable refcount display when hitting watchpoints" CR CR + " $P S b 4 off" CR " Temporarily disable breakpoint 4. This can be subsequently reenabled by a **s b 4 on**." CR //*********** check oplog syntax diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 1b1cb25215b..b8df289687b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1230,6 +1230,7 @@ zend_vm_enter: #endif #define DO_INTERACTIVE() do { \ + PHPDBG_G(lline) = zend_get_executed_lineno(TSRMLS_C);\ if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \ phpdbg_list_file( \ zend_get_executed_filename(TSRMLS_C), \ @@ -1331,7 +1332,10 @@ zend_vm_enter: } if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) { - DO_INTERACTIVE(); + if ((PHPDBG_G(flags) & PHPDBG_STEP_OPCODE) || + (execute_data->opline->lineno != PHPDBG_G(lline))) { + DO_INTERACTIVE(); + } } next: diff --git a/phpdbg_set.c b/phpdbg_set.c index aeb882657eb..54269a81931 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -40,6 +40,7 @@ const phpdbg_command_t phpdbg_set_commands[] = { PHPDBG_SET_COMMAND_D(break, "usage: set break id []", 'b', set_break, NULL, "l|b"), PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks []", 'B', set_breaks, NULL, "|b"), PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet []", 'q', set_quiet, NULL, "|b"), + PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping []", 's', set_stepping, NULL, "|s"), PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount []", 'r', set_refcount, NULL, "|b"), PHPDBG_END_COMMAND }; @@ -196,7 +197,8 @@ PHPDBG_SET(oplog) /* {{{ */ PHPDBG_SET(quiet) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + phpdbg_writeln("Quietness %s", + PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { @@ -212,10 +214,34 @@ PHPDBG_SET(quiet) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_SET(stepping) /* {{{ */ +{ + if (!param || param->type == EMPTY_PARAM) { + phpdbg_writeln("Stepping %s", + PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line"); + } else switch (param->type) { + case STR_PARAM: { + if ((param->len == sizeof("opcode")-1) && + (memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS)) { + PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE; + } else if ((param->len == sizeof("line")-1) && + (memcmp(param->str, "line", sizeof("line")) == SUCCESS)) { + PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE; + } else { + phpdbg_error("usage set stepping []"); + } + } break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + PHPDBG_SET(refcount) /* {{{ */ { if (!param || param->type == EMPTY_PARAM) { - phpdbg_writeln("Showing refcounts on watchpoints %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); + phpdbg_writeln("Refcount %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off"); } else switch (param->type) { case NUMERIC_PARAM: { if (param->num) { diff --git a/phpdbg_set.h b/phpdbg_set.h index 67bf4cd7def..dea61ed3825 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -34,6 +34,7 @@ PHPDBG_SET(oplog); PHPDBG_SET(break); PHPDBG_SET(breaks); PHPDBG_SET(quiet); +PHPDBG_SET(stepping); PHPDBG_SET(refcount); extern const phpdbg_command_t phpdbg_set_commands[]; From 0873f2bfb4f8ad0ecd5f4ae7805828ed34bc1565 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 21 Apr 2014 21:24:41 +0100 Subject: [PATCH 134/137] remove -e option in favour of taking script from argv[] --- phpdbg.c | 24 +++++++++++++----------- phpdbg_help.c | 1 - 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index 8fde93cd909..d7eb5c8b382 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -569,7 +569,6 @@ const opt_struct OPTIONS[] = { /* {{{ */ {'z', 1, "load zend_extension"}, /* phpdbg options */ {'q', 0, "no banner"}, - {'e', 1, "exec"}, {'v', 0, "disable quietness"}, {'s', 0, "enable stepping"}, {'b', 0, "boring colours"}, @@ -983,16 +982,6 @@ phpdbg_main: /* begin phpdbg options */ - case 'e': { /* set execution context */ - exec_len = strlen(php_optarg); - if (exec_len) { - if (exec) { - free(exec); - } - exec = strdup(php_optarg); - } - } break; - case 'S': { /* set SAPI name */ if (sapi_name) { free(sapi_name); @@ -1083,6 +1072,19 @@ phpdbg_main: } break; } } + + /* set exec if present on command line */ + if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) + { + exec_len = strlen(argv[php_optind]); + if (exec_len) { + if (exec) { + free(exec); + } + exec = strdup(argv[php_optind]); + } + php_optind++; + } #ifndef _WIN32 /* setup remote server if necessary */ diff --git a/phpdbg_help.c b/phpdbg_help.c index 2a6f9e82b65..f912f46787a 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -361,7 +361,6 @@ phpdbg_help_text_t phpdbg_help_text[] = { " **-d** **-d**memory_limit=4G Set a php.ini directive" CR " **-n** Disable default php.ini" CR " **-q** Supress welcome banner" CR -" **-e** **-e**mytest.php Set execution context" CR " **-v** Enable oplog output" CR " **-s** Enable stepping" CR " **-b** Disable colour" CR From e9668d4ce8512838d92b05aa47da02c85a37c486 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 21 Apr 2014 21:43:19 +0100 Subject: [PATCH 135/137] buffer input to repeat commands --- phpdbg.c | 8 ++++++-- phpdbg.h | 4 +--- phpdbg_cmd.c | 21 +++++++++++++++++++++ phpdbg_prompt.c | 15 ++------------- 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/phpdbg.c b/phpdbg.c index d7eb5c8b382..5b235ee3a8f 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -61,16 +61,15 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->exec = NULL; pg->exec_len = 0; + pg->buffer = NULL; pg->ops = NULL; pg->vmret = 0; pg->bp_count = 0; - pg->lcmd = NULL; pg->flags = PHPDBG_DEFAULT_FLAGS; pg->oplog = NULL; pg->io[PHPDBG_STDIN] = NULL; pg->io[PHPDBG_STDOUT] = NULL; pg->io[PHPDBG_STDERR] = NULL; - memset(&pg->lparam, 0, sizeof(phpdbg_param_t)); pg->frame.num = 0; } /* }}} */ @@ -184,6 +183,11 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(watchpoints)); zend_llist_destroy(&PHPDBG_G(watchlist_mem)); + if (PHPDBG_G(buffer)) { + efree(PHPDBG_G(buffer)); + PHPDBG_G(buffer) = NULL; + } + if (PHPDBG_G(exec)) { efree(PHPDBG_G(exec)); PHPDBG_G(exec) = NULL; diff --git a/phpdbg.h b/phpdbg.h index d25e0be4379..be009e40d04 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -199,9 +199,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) char *prompt[2]; /* prompt */ const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */ - - phpdbg_command_t *lcmd; /* last command */ - phpdbg_param_t lparam; /* last param */ + char *buffer; /* buffer */ zend_ulong flags; /* phpdbg flags */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index ce66ba39eca..d4ce8ebc55f 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -858,6 +858,27 @@ readline: #endif } + if (buffer && isspace(*buffer)) { + char *trimmed = buffer; + while (isspace(*trimmed)) + trimmed++; + + trimmed = estrdup(trimmed); + efree(buffer); + buffer = trimmed; + } + + if (buffer && strlen(buffer)) { + if (PHPDBG_G(buffer)) { + efree(PHPDBG_G(buffer)); + } + PHPDBG_G(buffer) = estrdup(buffer); + } else { + if (PHPDBG_G(buffer)) { + buffer = estrdup(PHPDBG_G(buffer)); + } + } + return buffer; } /* }}} */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d93b55374e4..2e07c321747 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -1028,13 +1028,13 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ if (yyparse(&stack, scanner) <= 0) { switch (ret = phpdbg_stack_execute(&stack, &why TSRMLS_CC)) { case FAILURE: -// if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { if (why) { phpdbg_error("%s", why); } } -// } + } if (why) { free(why); @@ -1066,17 +1066,6 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ phpdbg_destroy_input(&input TSRMLS_CC); } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); - - if (!input) - goto last; - - } else { -last: - if (PHPDBG_G(lcmd)) { - ret = PHPDBG_G(lcmd)->handler( - &PHPDBG_G(lparam) TSRMLS_CC); - goto out; - } } out: From c1e12316f1126ae3b3867a38d6930cf66cfb0675 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 21 Apr 2014 22:00:21 +0100 Subject: [PATCH 136/137] fixup help, behaviour of step command when not executing --- phpdbg_help.c | 12 +++++++----- phpdbg_prompt.c | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/phpdbg_help.c b/phpdbg_help.c index 32a78cb0635..f2d074ded60 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -711,11 +711,13 @@ phpdbg_help_text_t phpdbg_help_text[] = { "populate these tables for a given execution context." }, -//*********** what is the difference between n and s ??? {"continue", -"The **continue** command causes control to be passed back to the vm, continuing execution. The next " -"opline will be executed if **step** is set **on**. Otherwise execution will continue to the next " -"breakpoint or script completion" CR CR +"Continue with execution after hitting a break or watchpoint" CR CR + +"**Examples**" CR CR +" $P continue" CR +" $P c" CR +" Continue executing until the next break or watchpoint" CR CR "Note **continue** will trigger a \"not running\" error if not executing." }, @@ -863,7 +865,7 @@ phpdbg_help_text_t phpdbg_help_text[] = { }, {"step", -"Execute opcodes until beginning on next line" CR CR +"Execute opcodes until next line" CR CR "**Examples**" CR CR diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 2e07c321747..e2603a00ed3 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -424,7 +424,9 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ PHPDBG_COMMAND(step) /* {{{ */ { - PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + if (EG(in_execution)) { + PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; + } return PHPDBG_NEXT; } /* }}} */ From 447ec05f3160628ef6dc7f7eee34bae866af8e5c Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 21 Apr 2014 23:14:06 +0200 Subject: [PATCH 137/137] Fixed infinite loop when quitting (sometimes) --- phpdbg_prompt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index e2603a00ed3..7a28a75129f 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -920,7 +920,7 @@ PHPDBG_COMMAND(quit) /* {{{ */ zend_bailout(); } - return SUCCESS; + return PHPDBG_NEXT; } /* }}} */ PHPDBG_COMMAND(clean) /* {{{ */ @@ -1048,7 +1048,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ case PHPDBG_FINISH: case PHPDBG_UNTIL: case PHPDBG_NEXT: { - if (!EG(in_execution)) { + if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { phpdbg_error("Not running"); } goto out;