summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sapi/phpdbg/phpdbg.c1
-rw-r--r--sapi/phpdbg/phpdbg.h9
-rw-r--r--sapi/phpdbg/phpdbg_io.c36
-rw-r--r--sapi/phpdbg/phpdbg_set.c38
-rw-r--r--sapi/phpdbg/phpdbg_set.h2
-rw-r--r--sapi/phpdbg/phpdbg_utils.c18
-rw-r--r--sapi/phpdbg/phpdbg_utils.h5
7 files changed, 103 insertions, 6 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 7a96f0ba09..a82292ac5a 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -81,6 +81,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
pg->colors[1] = NULL;
pg->colors[2] = NULL;
+ pg->lines = phpdbg_get_terminal_height();
pg->exec = NULL;
pg->exec_len = 0;
pg->buffer = NULL;
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index 56a0714758..63b05cd806 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -195,17 +195,19 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input);
#define PHPDBG_DISCARD_OUTPUT (1ULL<<35)
+#define PHPDBG_HAS_PAGINATION (1ULL<<36)
+
#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)
#define PHPDBG_IS_STOPPING (PHPDBG_IS_QUITTING | PHPDBG_IS_CLEANING)
-#define PHPDBG_PRESERVE_FLAGS_MASK (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_REMOTE | PHPDBG_WRITE_XML | PHPDBG_IS_DISCONNECTED)
+#define PHPDBG_PRESERVE_FLAGS_MASK (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_REMOTE | PHPDBG_WRITE_XML | PHPDBG_IS_DISCONNECTED | PHPDBG_HAS_PAGINATION)
#ifndef _WIN32
-# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_BP_ENABLED)
+# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_BP_ENABLED | PHPDBG_HAS_PAGINATION)
#else
-# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_BP_ENABLED)
+# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_BP_ENABLED | PHPDBG_HAS_PAGINATION)
#endif /* }}} */
/* {{{ output descriptors */
@@ -314,6 +316,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HANDLE sigio_watcher_thread; /* sigio watcher thread handle */
struct win32_sigio_watcher_data swd;
#endif
+ long lines; /* max number of lines to display */
ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
#endif
diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c
index baec0ac0f8..cf4fdb88b4 100644
--- a/sapi/phpdbg/phpdbg_io.c
+++ b/sapi/phpdbg/phpdbg_io.c
@@ -190,16 +190,50 @@ PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo) {
return ret;
}
+static int phpdbg_output_pager(int sock, const char *ptr, int len) {
+ int count = 0, bytes = 0;
+ const char *p = ptr, *endp = ptr + len;
+
+ while ((p = memchr(p, '\n', endp - p))) {
+ count++;
+ p++;
+
+ if (count % PHPDBG_G(lines) == 0) {
+ bytes += write(sock, ptr + bytes, (p - ptr) - bytes);
+
+ if (memchr(p, '\n', endp - p)) {
+ int chr;
+ printf("\r---Type <return> to continue or q <return> to quit---");
+ chr = getchar();
+ if (chr == 'q') {
+ break;
+ }
+ printf("\r");
+ } else break;
+ }
+ }
+ if (bytes && count % PHPDBG_G(lines) != 0) {
+ bytes += write(sock, ptr + bytes, len - bytes);
+ } else if (!bytes) {
+ bytes += write(sock, ptr, len);
+ }
+ return bytes;
+}
PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len) {
if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) {
return phpdbg_send_bytes(sock, ptr, len);
}
+
+ if (PHPDBG_G(flags) & PHPDBG_HAS_PAGINATION
+ && PHPDBG_G(io)[PHPDBG_STDOUT].fd == sock
+ && PHPDBG_G(lines) > 0) {
+ return phpdbg_output_pager(sock, ptr, len);
+ }
return write(sock, ptr, len);
}
-
PHPDBG_API int phpdbg_open_socket(const char *interface, unsigned short port) {
struct addrinfo res;
int fd = phpdbg_create_listenable_socket(interface, port, &res);
diff --git a/sapi/phpdbg/phpdbg_set.c b/sapi/phpdbg/phpdbg_set.c
index f91156a452..5af2c593c8 100644
--- a/sapi/phpdbg/phpdbg_set.c
+++ b/sapi/phpdbg/phpdbg_set.c
@@ -32,6 +32,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
const phpdbg_command_t phpdbg_set_commands[] = {
PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s", 0),
+ PHPDBG_SET_COMMAND_D(pagination, "usage: set pagination [<on|off>]", 'P', set_pagination, NULL, "|b", PHPDBG_ASYNC_SAFE),
#ifndef _WIN32
PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss", PHPDBG_ASYNC_SAFE),
PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b", PHPDBG_ASYNC_SAFE),
@@ -42,6 +43,7 @@ const phpdbg_command_t phpdbg_set_commands[] = {
PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b", PHPDBG_ASYNC_SAFE),
PHPDBG_SET_COMMAND_D(stepping, "usage: set stepping [<line|op>]", 's', set_stepping, NULL, "|s", PHPDBG_ASYNC_SAFE),
PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b", PHPDBG_ASYNC_SAFE),
+ PHPDBG_SET_COMMAND_D(lines, "usage: set lines [<number>]", 'l', set_lines, NULL, "|l", PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
@@ -56,6 +58,42 @@ PHPDBG_SET(prompt) /* {{{ */
return SUCCESS;
} /* }}} */
+PHPDBG_SET(pagination) /* {{{ */
+{
+ if (!param || param->type == EMPTY_PARAM) {
+ phpdbg_writeln("setpagination", "active=\"%s\"", "Pagination %s", PHPDBG_G(flags) & PHPDBG_HAS_PAGINATION ? "on" : "off");
+ } else switch (param->type) {
+ case NUMERIC_PARAM: {
+ if (param->num) {
+ PHPDBG_G(flags) |= PHPDBG_HAS_PAGINATION;
+ } else {
+ PHPDBG_G(flags) &= ~PHPDBG_HAS_PAGINATION;
+ }
+ } break;
+
+ default:
+ phpdbg_error("setpagination", "type=\"wrongargs\"", "set pagination used incorrectly: set pagination <on|off>");
+ }
+
+ return SUCCESS;
+} /* }}} */
+
+PHPDBG_SET(lines) /* {{{ */
+{
+ if (!param || param->type == EMPTY_PARAM) {
+ phpdbg_writeln("setlines", "active=\"%s\"", "Lines %ld", PHPDBG_G(lines));
+ } else switch (param->type) {
+ case NUMERIC_PARAM: {
+ PHPDBG_G(lines) = param->num;
+ } break;
+
+ default:
+ phpdbg_error("setlines", "type=\"wrongargs\"", "set lines used incorrectly: set lines <number>");
+ }
+
+ return SUCCESS;
+} /* }}} */
+
PHPDBG_SET(break) /* {{{ */
{
switch (param->type) {
diff --git a/sapi/phpdbg/phpdbg_set.h b/sapi/phpdbg/phpdbg_set.h
index 9b2e1ce14e..b4102f50b2 100644
--- a/sapi/phpdbg/phpdbg_set.h
+++ b/sapi/phpdbg/phpdbg_set.h
@@ -36,6 +36,8 @@ PHPDBG_SET(breaks);
PHPDBG_SET(quiet);
PHPDBG_SET(stepping);
PHPDBG_SET(refcount);
+PHPDBG_SET(pagination);
+PHPDBG_SET(lines);
extern const phpdbg_command_t phpdbg_set_commands[];
diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c
index e9b30c07b1..92beda3c4f 100644
--- a/sapi/phpdbg/phpdbg_utils.c
+++ b/sapi/phpdbg/phpdbg_utils.c
@@ -351,6 +351,24 @@ PHPDBG_API int phpdbg_get_terminal_width(void) /* {{{ */
return columns;
} /* }}} */
+PHPDBG_API int phpdbg_get_terminal_height(void) /* {{{ */
+{
+ int lines;
+#ifdef _WIN32
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
+ lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+#elif defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
+ struct winsize w;
+
+ lines = ioctl(fileno(stdout), TIOCGWINSZ, &w) == 0 ? w.ws_row : 40;
+#else
+ lines = 40;
+#endif
+ return lines;
+} /* }}} */
+
PHPDBG_API void phpdbg_set_async_io(int fd) {
#if !defined(_WIN32) && defined(FASYNC)
int flags;
diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h
index d4fd352cd4..8cf7acc2ce 100644
--- a/sapi/phpdbg/phpdbg_utils.h
+++ b/sapi/phpdbg/phpdbg_utils.h
@@ -73,8 +73,9 @@ PHPDBG_API int phpdbg_get_element(const char *name, size_t len); /* }}} */
PHPDBG_API void phpdbg_set_prompt(const char*);
PHPDBG_API const char *phpdbg_get_prompt(void); /* }}} */
-/* {{{ Console Width */
-PHPDBG_API int phpdbg_get_terminal_width(void); /* }}} */
+/* {{{ Console size */
+PHPDBG_API int phpdbg_get_terminal_width(void);
+PHPDBG_API int phpdbg_get_terminal_height(void); /* }}} */
PHPDBG_API void phpdbg_set_async_io(int fd);