Permalink
Browse files

- Added ANSI colour output for the shell. (Patch by Michael Maclean).

SVN Rev: 3337
  • Loading branch information...
1 parent b6844bf commit 23c5739ee923938aba0c029d3971db563cb43606 @derickr derickr committed Aug 7, 2010
Showing with 419 additions and 11 deletions.
  1. +15 −0 php_xdebug.h
  2. +50 −2 xdebug.c
  3. +39 −9 xdebug_stack.c
  4. +306 −0 xdebug_var.c
  5. +9 −0 xdebug_var.h
View
@@ -38,6 +38,12 @@ extern zend_module_entry xdebug_module_entry;
#define MICRO_IN_SEC 1000000.00
+#ifndef PHP_WIN32
+#define OUTPUT_NOT_CHECKED -1
+#define OUTPUT_IS_TTY 1
+#define OUTPUT_NOT_TTY 0
+#endif
+
#ifdef PHP_WIN32
#define PHP_XDEBUG_API __declspec(dllexport)
#else
@@ -81,6 +87,10 @@ PHP_RSHUTDOWN_FUNCTION(xdebug);
PHP_MINFO_FUNCTION(xdebug);
ZEND_MODULE_POST_ZEND_DEACTIVATE_D(xdebug);
+#ifndef PHP_WIN32
+int xdebug_is_output_tty();
+#endif
+
/* call stack functions */
PHP_FUNCTION(xdebug_get_stack_depth);
PHP_FUNCTION(xdebug_get_function_stack);
@@ -177,6 +187,11 @@ ZEND_BEGIN_MODULE_GLOBALS(xdebug)
long display_max_data;
long display_max_depth;
+#ifndef PHP_WIN32
+ zend_bool cli_color;
+ int output_is_tty;
+#endif
+
/* used for code coverage */
zend_bool do_code_coverage;
xdebug_hash *code_coverage;
View
@@ -292,6 +292,9 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("xdebug.var_display_max_children", "128", PHP_INI_ALL, OnUpdateLong, display_max_children, zend_xdebug_globals, xdebug_globals)
STD_PHP_INI_ENTRY("xdebug.var_display_max_data", "512", PHP_INI_ALL, OnUpdateLong, display_max_data, zend_xdebug_globals, xdebug_globals)
STD_PHP_INI_ENTRY("xdebug.var_display_max_depth", "3", PHP_INI_ALL, OnUpdateLong, display_max_depth, zend_xdebug_globals, xdebug_globals)
+#ifndef PHP_WIN32
+ STD_PHP_INI_ENTRY("xdebug.cli_color", "0", PHP_INI_ALL, OnUpdateBool, cli_color, zend_xdebug_globals, xdebug_globals)
+#endif
/* Scream support */
STD_PHP_INI_BOOLEAN("xdebug.scream", "0", PHP_INI_ALL, OnUpdateBool, do_scream, zend_xdebug_globals, xdebug_globals)
@@ -308,6 +311,7 @@ static void php_xdebug_init_globals (zend_xdebug_globals *xg TSRMLS_DC)
xg->do_code_coverage = 0;
xg->breakpoint_count = 0;
xg->ide_key = NULL;
+ xg->output_is_tty = OUTPUT_NOT_CHECKED;
xdebug_llist_init(&xg->server, xdebug_superglobals_dump_dtor);
xdebug_llist_init(&xg->get, xdebug_superglobals_dump_dtor);
@@ -423,6 +427,11 @@ void xdebug_env_config()
if (strcasecmp(envvar, "remote_cookie_expire_time") == 0) {
name = "xdebug.remote_cookie_expire_time";
}
+#ifndef PHP_WIN32
+ else if (strcasecmp(envvar, "cli_color") == 0) {
+ name = "xdebug.cli_color";
+ }
+#endif
if (name) {
zend_alter_ini_entry(name, strlen(name) + 1, envval, strlen(envval), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
@@ -478,6 +487,26 @@ static int xdebug_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
return ZEND_USER_OPCODE_DISPATCH;
}
+#ifndef PHP_WIN32
+int xdebug_is_output_tty()
+{
+ if (XG(output_is_tty) == OUTPUT_NOT_CHECKED) {
+ php_stream *output = php_stream_open_wrapper("php://stdout", "w", REPORT_ERRORS, NULL);
+ int fd;
+
+ if (php_stream_cast(output, PHP_STREAM_AS_FD, (void *)&fd, REPORT_ERRORS) == FAILURE) {
+ XG(output_is_tty) = OUTPUT_NOT_TTY;
+ } else if (!isatty(fd)) {
+ XG(output_is_tty) = OUTPUT_NOT_TTY;
+ } else {
+ XG(output_is_tty) = OUTPUT_IS_TTY;
+ }
+ php_stream_close(output);
+ }
+ return (XG(output_is_tty));
+}
+#endif
+
PHP_MINIT_FUNCTION(xdebug)
{
@@ -584,6 +613,10 @@ PHP_MINIT_FUNCTION(xdebug)
REGISTER_LONG_CONSTANT("XDEBUG_CC_DEAD_CODE", XDEBUG_CC_OPTION_DEAD_CODE, CONST_CS | CONST_PERSISTENT);
XG(breakpoint_count) = 0;
+#ifndef PHP_WIN32
+ XG(output_is_tty) = OUTPUT_NOT_CHECKED;
+#endif
+
#ifndef ZTS
if (sapi_module.header_handler != xdebug_header_handler) {
xdebug_orig_header_handler = sapi_module.header_handler;
@@ -1436,7 +1469,15 @@ PHP_FUNCTION(xdebug_var_dump)
val = xdebug_get_zval_value_fancy(NULL, (zval*) *args[i], &len, 0, NULL TSRMLS_CC);
PHPWRITE(val, len);
xdfree(val);
- } else {
+ }
+#ifndef PHP_WIN32
+ else if (XG(cli_color) == 1 && xdebug_is_output_tty(TSRMLS_C)) {
+ val = xdebug_get_zval_value_ansi((zval*) *args[i], 0, NULL TSRMLS_CC);
+ PHPWRITE(val, strlen(val));
+ xdfree(val);
+ }
+#endif
+ else {
xdebug_php_var_dump(args[i], 1 TSRMLS_CC);
}
}
@@ -1478,7 +1519,14 @@ PHP_FUNCTION(xdebug_debug_zval)
if (PG(html_errors)) {
val = xdebug_get_zval_value_fancy(NULL, debugzval, &len, 1, NULL TSRMLS_CC);
PHPWRITE(val, len);
- } else {
+ }
+#ifndef PHP_WIN32
+ else if (XG(cli_color) == 1 && xdebug_is_output_tty(TSRMLS_C)) {
+ val = xdebug_get_zval_value_ansi(debugzval, 1, NULL TSRMLS_CC);
+ PHPWRITE(val, strlen(val));
+ }
+#endif
+ else {
val = xdebug_get_zval_value(debugzval, 1, NULL);
PHPWRITE(val, strlen(val));
}
View
@@ -24,6 +24,7 @@
#include "xdebug_str.h"
#include "xdebug_superglobals.h"
#include "xdebug_var.h"
+#include "php_ini.h"
#include "main/php_ini.h"
@@ -46,6 +47,25 @@ static char* text_formats[10] = {
" $%s = *uninitialized*\n"
};
+#ifndef PHP_WIN32
+static char* ansi_formats[10] = {
+ "\n",
+ "\e[1m\e[31m%s\e[0m: %s\e[22m in \e[31m%s\e[0m on line \e[32m%d\e[0m\e[22m\n",
+ "\n\e[1mCall Stack:\e[22m\n",
+#if HAVE_PHP_MEMORY_USAGE
+ "%10.4f %10ld %3d. %s(",
+#else
+ "%10.4f %3d. %s(",
+#endif
+ "'%s'",
+ ") %s:%d\n",
+ "\n\nVariables in local scope (#%d):\n",
+ "\n",
+ " $%s = %s\n",
+ " $%s = *uninitialized*\n"
+};
+#endif
+
static char* html_formats[12] = {
"<br />\n<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>\n",
"<tr><th align='left' bgcolor='#f57900' colspan=\"5\"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> %s: %s in %s on line <i>%d</i></th></tr>\n",
@@ -70,6 +90,20 @@ static char* html_formats[12] = {
"<tr><th align='left' bgcolor='#f57900' colspan=\"5\"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> %s: %s in <a style='color: black' href='%s'>%s</a> on line <i>%d</i></th></tr>\n"
};
+static char** select_formats(int html TSRMLS_DC) {
+ if (html) {
+ return html_formats;
+ }
+#ifndef PHP_WIN32
+ else if (XG(cli_color) == 1 && xdebug_is_output_tty(TSRMLS_C)) {
+ return ansi_formats;
+ }
+#endif
+ else {
+ return text_formats;
+ }
+}
+
static void dump_used_var_with_contents(void *htmlq, xdebug_hash_element* he, void *argument)
{
int html = *(int *)htmlq;
@@ -102,11 +136,7 @@ static void dump_used_var_with_contents(void *htmlq, xdebug_hash_element* he, vo
zvar = xdebug_get_php_symbol(name, strlen(name) + 1);
XG(active_symbol_table) = tmp_ht;
- if (html) {
- formats = html_formats;
- } else {
- formats = text_formats;
- }
+ formats = select_formats(PG(html_errors));
if (!zvar) {
xdebug_str_add(str, xdebug_sprintf(formats[9], name), 1);
@@ -218,14 +248,14 @@ static int create_file_link(char **filename, const char *error_filename, int err
static void xdebug_append_error_head(xdebug_str *str, int html TSRMLS_DC)
{
- char **formats = html ? html_formats : text_formats;
+ char **formats = select_formats(html TSRMLS_CC);
xdebug_str_add(str, formats[0], 0);
}
void xdebug_append_error_description(xdebug_str *str, int html, const char *error_type_str, char *buffer, const char *error_filename, const int error_lineno TSRMLS_DC)
{
- char **formats = html ? html_formats : text_formats;
+ char **formats = select_formats(html TSRMLS_CC);
if (strlen(XG(file_link_format)) > 0 && html) {
char *file_link;
@@ -243,7 +273,7 @@ void xdebug_append_printable_stack(xdebug_str *str, int html TSRMLS_DC)
xdebug_llist_element *le;
function_stack_entry *i;
int len;
- char **formats = html ? html_formats : text_formats;
+ char **formats = select_formats(html TSRMLS_CC);
if (XG(stack) && XG(stack)->size) {
i = XDEBUG_LLIST_VALP(XDEBUG_LLIST_HEAD(XG(stack)));
@@ -388,7 +418,7 @@ void xdebug_append_printable_stack(xdebug_str *str, int html TSRMLS_DC)
static void xdebug_append_error_footer(xdebug_str *str, int html)
{
- char **formats = html ? html_formats : text_formats;
+ char **formats = select_formats(html TSRMLS_CC);
xdebug_str_add(str, formats[7], 0);
}
Oops, something went wrong. Retry.

0 comments on commit 23c5739

Please sign in to comment.