get good control over colors and prompt

This commit is contained in:
krakjoe 2013-11-24 19:34:18 +00:00
parent c85f247eac
commit ddcfa42f15
7 changed files with 207 additions and 160 deletions

View file

@ -37,9 +37,13 @@ void (*zend_execute_old)(zend_op_array *op_array TSRMLS_DC);
static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
{ {
pg->prompt = NULL; pg->prompt[0] = NULL;
pg->prompt_raw = NULL; pg->prompt[1] = NULL;
pg->prompt_color = NULL;
pg->colors[0] = NULL;
pg->colors[1] = NULL;
pg->colors[2] = NULL;
pg->exec = NULL; pg->exec = NULL;
pg->exec_len = 0; pg->exec_len = 0;
pg->ops = NULL; pg->ops = NULL;
@ -151,20 +155,15 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
PHPDBG_G(exec) = NULL; PHPDBG_G(exec) = NULL;
} }
if (PHPDBG_G(prompt)) { if (PHPDBG_G(prompt)[0]) {
efree(PHPDBG_G(prompt)); free(PHPDBG_G(prompt)[0]);
PHPDBG_G(prompt) = NULL; }
if (PHPDBG_G(prompt)[1]) {
free(PHPDBG_G(prompt)[1]);
} }
if (PHPDBG_G(prompt_raw)) { PHPDBG_G(prompt)[0] = NULL;
efree(PHPDBG_G(prompt_raw)); PHPDBG_G(prompt)[1] = NULL;
PHPDBG_G(prompt_raw) = NULL;
}
if (PHPDBG_G(prompt_color)) {
efree(PHPDBG_G(prompt_color));
PHPDBG_G(prompt_color) = NULL;
}
if (PHPDBG_G(oplog)) { if (PHPDBG_G(oplog)) {
fclose( fclose(
@ -698,8 +697,13 @@ phpdbg_main:
/* set flags from command line */ /* set flags from command line */
PHPDBG_G(flags) = flags; PHPDBG_G(flags) = flags;
/* set default colors */
phpdbg_set_color_ex(PHPDBG_COLOR_PROMPT, "white-bold", sizeof("white-bold")-1 TSRMLS_CC);
phpdbg_set_color_ex(PHPDBG_COLOR_ERROR, "red", sizeof("red")-1 TSRMLS_CC);
phpdbg_set_color_ex(PHPDBG_COLOR_NOTICE, "green", sizeof("green")-1 TSRMLS_CC);
/* set default prompt */ /* set default prompt */
phpdbg_set_prompt(PROMPT, "1;64" TSRMLS_CC); phpdbg_set_prompt(PROMPT TSRMLS_CC);
zend_try { zend_try {
zend_activate_modules(TSRMLS_C); zend_activate_modules(TSRMLS_C);

View file

@ -62,6 +62,7 @@
#endif #endif
#include "phpdbg_cmd.h" #include "phpdbg_cmd.h"
#include "phpdbg_utils.h"
#ifdef ZTS #ifdef ZTS
# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v)
@ -112,7 +113,6 @@
#define PHPDBG_IS_SIGNALED (1<<20) #define PHPDBG_IS_SIGNALED (1<<20)
#define PHPDBG_IS_INTERACTIVE (1<<21) #define PHPDBG_IS_INTERACTIVE (1<<21)
#ifndef _WIN32 #ifndef _WIN32
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED) # define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED)
#else #else
@ -126,14 +126,16 @@
/* {{{ output descriptors */ /* {{{ output descriptors */
#define PHPDBG_STDIN 0 #define PHPDBG_STDIN 0
#define PHPDBG_STDOUT 1 #define PHPDBG_STDOUT 1
#define PHPDBG_STDERR 2 /* }}} */ #define PHPDBG_STDERR 2
#define PHPDBG_IO_FDS 3 /* }}} */
/* {{{ structs */ /* {{{ structs */
ZEND_BEGIN_MODULE_GLOBALS(phpdbg) ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */
char *prompt; /* prompt */ HashTable registered; /* registered */
char *prompt_raw; /* prompt unmodified */ HashTable seek; /* seek oplines */
char *prompt_color; /* prompt color */ phpdbg_frame_t frame; /* frame */
char *exec; /* file to execute */ char *exec; /* file to execute */
size_t exec_len; /* size of exec */ size_t exec_len; /* size of exec */
zend_op_array *ops; /* op_array */ zend_op_array *ops; /* op_array */
@ -141,14 +143,17 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
int bp_count; /* breakpoint count */ int bp_count; /* breakpoint count */
int del_bp_num; /* breakpoint to delete */ int del_bp_num; /* breakpoint to delete */
int vmret; /* return from last opcode handler execution */ int vmret; /* return from last opcode handler execution */
FILE *oplog; /* opline log */
FILE *io[PHPDBG_IO_FDS]; /* io */
char *prompt[2]; /* prompt */
const phpdbg_color_t *colors[PHPDBG_COLORS]; /* colors */
phpdbg_command_t *lcmd; /* last command */ phpdbg_command_t *lcmd; /* last command */
phpdbg_param_t lparam; /* last param */ phpdbg_param_t lparam; /* last param */
FILE *oplog; /* opline log */
HashTable seek; /* seek oplines */
zend_ulong flags; /* phpdbg flags */ zend_ulong flags; /* phpdbg flags */
HashTable registered; /* registered */
phpdbg_frame_t frame; /* frame */
FILE *io[3]; /* stdin/stdout/stderr */
ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
#endif /* PHPDBG_H */ #endif /* PHPDBG_H */

View file

@ -92,6 +92,8 @@ typedef struct {
} phpdbg_frame_t; } phpdbg_frame_t;
/* }}} */ /* }}} */
/* /*
* Workflow: * Workflow:
* 1) read input * 1) read input
@ -112,6 +114,8 @@ typedef struct {
PHPDBG_API phpdbg_input_t* phpdbg_read_input(char *buffered TSRMLS_DC); PHPDBG_API phpdbg_input_t* phpdbg_read_input(char *buffered TSRMLS_DC);
PHPDBG_API phpdbg_input_t** phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC); PHPDBG_API phpdbg_input_t** phpdbg_read_argv(char *buffer, int *argc TSRMLS_DC);
PHPDBG_API void phpdbg_destroy_input(phpdbg_input_t** TSRMLS_DC); PHPDBG_API void phpdbg_destroy_input(phpdbg_input_t** TSRMLS_DC);
#define phpdbg_argv_is(n, s) \
(memcmp(input->argv[n]->string, s, input->argv[n]->length-1) == SUCCESS)
/* /*
* Parameter Management * Parameter Management

View file

@ -24,67 +24,6 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg); ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
void phpdbg_set_prompt(const char *prompt, const char *color TSRMLS_DC) /* {{{ */
{
char *old_prompt_raw = PHPDBG_G(prompt_raw);
if (PHPDBG_G(prompt)) {
efree(PHPDBG_G(prompt));
PHPDBG_G(prompt) = NULL;
}
if (color) {
if (PHPDBG_G(prompt_color)) {
efree(PHPDBG_G(prompt_color));
}
PHPDBG_G(prompt_color) = estrdup(color);
}
if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
spprintf(&PHPDBG_G(prompt), 0, "\033[%sm%s\033[0m ",
PHPDBG_G(prompt_color) ? PHPDBG_G(prompt_color) : "1;64", prompt);
} else {
spprintf(&PHPDBG_G(prompt), 0, "%s ", prompt);
}
PHPDBG_G(prompt_raw) = estrdup(prompt);
if (old_prompt_raw) {
efree(old_prompt_raw);
}
} /* }}} */
const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */
{
return PHPDBG_G(prompt);
} /* }}} */
void phpdbg_set_prompt_color(const char *color TSRMLS_DC) /* {{{ */
{
static const char *colors[] = {
"blue", "0;34",
"green", "0;32",
"red", "0;31",
"cyan", "0;36",
"purple", "0;35",
NULL, NULL
};
const char **p = colors;
do {
if (memcmp(color, *p, strlen(*p)+1) == 0) {
PHPDBG_G(prompt_color) = estrdup(*p);
phpdbg_set_prompt(PHPDBG_G(prompt_raw), *(p+1) TSRMLS_CC);
return;
}
} while (++p && *(++p));
} /* }}} */
const char* phpdbg_get_prompt_color(TSRMLS_D) /* {{{ */
{
return PHPDBG_G(prompt_color);
} /* }}} */
PHPDBG_SET(prompt) /* {{{ */ PHPDBG_SET(prompt) /* {{{ */
{ {
switch (param->type) { switch (param->type) {
@ -93,7 +32,7 @@ PHPDBG_SET(prompt) /* {{{ */
break; break;
case STR_PARAM: case STR_PARAM:
phpdbg_set_prompt(param->str, NULL TSRMLS_CC); phpdbg_set_prompt(param->str TSRMLS_CC);
break; break;
phpdbg_default_switch_case(); phpdbg_default_switch_case();
@ -102,20 +41,45 @@ PHPDBG_SET(prompt) /* {{{ */
return SUCCESS; return SUCCESS;
} /* }}} */ } /* }}} */
PHPDBG_SET(prompt_color) /* {{{ */ PHPDBG_SET(color) /* {{{ */
{ {
switch (param->type) { if ((param->type == STR_PARAM) && (input->argc == 3)) {
case EMPTY_PARAM: const phpdbg_color_t *color = phpdbg_get_color(
phpdbg_writeln(phpdbg_get_prompt_color(TSRMLS_C)); input->argv[2]->string, input->argv[2]->length TSRMLS_CC);
break; int element = PHPDBG_COLOR_INVALID;
case STR_PARAM: if (color) {
phpdbg_set_prompt_color(param->str TSRMLS_CC); if (phpdbg_argv_is(1, "prompt")) {
break; phpdbg_notice(
"setting prompt color to %s (%s)", color->name, color->code);
phpdbg_default_switch_case(); 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;
/* set color for element */
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 incorrected: set color <prompt|error|notice> <color>");
}
return SUCCESS; return SUCCESS;
} /* }}} */ } /* }}} */

View file

@ -24,22 +24,15 @@
#define PHPDBG_SET(name) PHPDBG_COMMAND(set_##name) #define PHPDBG_SET(name) PHPDBG_COMMAND(set_##name)
void phpdbg_set_prompt(const char*, const char* TSRMLS_DC);
const char *phpdbg_get_prompt(TSRMLS_D);
void phpdbg_set_prompt_color(const char* TSRMLS_DC);
const char *phpdbg_get_prompt_color(TSRMLS_D);
PHPDBG_SET(prompt); PHPDBG_SET(prompt);
PHPDBG_SET(prompt_color); PHPDBG_SET(color);
PHPDBG_SET(oplog); PHPDBG_SET(oplog);
static const phpdbg_command_t phpdbg_set_commands[] = { static const phpdbg_command_t phpdbg_set_commands[] = {
PHPDBG_COMMAND_D_EX(prompt, "set prompt", 'p', set_prompt, NULL, 0), PHPDBG_COMMAND_D_EX(prompt, "set prompt <string>", 'p', set_prompt, NULL, 0),
PHPDBG_COMMAND_D_EX(prompt_color, "set prompt color", 'c', set_prompt_color, NULL, 0), PHPDBG_COMMAND_D_EX(color, "set color <element> <color>", 'C', set_color, NULL, 1),
PHPDBG_COMMAND_D_EX(oplog, "set oplog output", 'O', set_oplog, NULL, 0), PHPDBG_COMMAND_D_EX(oplog, "set oplog <output>", 'O', set_oplog, NULL, 0),
PHPDBG_END_COMMAND PHPDBG_END_COMMAND
}; };
#endif /* PHPDBG_SET_H */ #endif /* PHPDBG_SET_H */

View file

@ -34,12 +34,20 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
/* {{{ color structures */ /* {{{ color structures */
const static phpdbg_color_t colors[] = { const static phpdbg_color_t colors[] = {
PHPDBG_COLOR_D("white", "0:0"), PHPDBG_COLOR_D("none", "0;0"),
PHPDBG_COLOR_D("red", "0:31"),
PHPDBG_COLOR_D("green", "0:32"), PHPDBG_COLOR_D("white", "0;64"),
PHPDBG_COLOR_D("white-bold", "1;64"),
PHPDBG_COLOR_D("red", "0;31"),
PHPDBG_COLOR_D("red-bold", "1;31"),
PHPDBG_COLOR_D("green", "0;32"),
PHPDBG_COLOR_D("green-bold", "1;32"),
PHPDBG_COLOR_D("blue", "0;34"), PHPDBG_COLOR_D("blue", "0;34"),
PHPDBG_COLOR_D("blue-bold", "1;34"),
PHPDBG_COLOR_D("purple", "0;35"), PHPDBG_COLOR_D("purple", "0;35"),
PHPDBG_COLOR_D("purple-bold", "1;35"),
PHPDBG_COLOR_D("cyan", "0;36"), PHPDBG_COLOR_D("cyan", "0;36"),
PHPDBG_COLOR_D("cyan-bold", "1;36"),
PHPDBG_COLOR_END PHPDBG_COLOR_END
}; /* }}} */ }; /* }}} */
@ -170,35 +178,35 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ..
switch (type) { switch (type) {
case P_ERROR: case P_ERROR:
rc = fprintf(fp, "%s%s%s\n", if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[1;31m[" : "["), rc = fprintf(fp,
buffer, "\033[%sm[%s]\033[0m\n",
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "]\033[0m" : "]")); PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, buffer);
} else {
rc = fprintf(fp, "[%s]\n", buffer);
}
break; break;
case P_NOTICE: case P_NOTICE:
rc = fprintf(fp, "%s%s%s\n", if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[1;64m[" : "["), rc = fprintf(fp,
buffer, "\033[%sm[%s]\033[0m\n",
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "]\033[0m" : "]")); PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, buffer);
} else {
rc = fprintf(fp, "[%s]\n", buffer);
}
break; break;
case P_WRITELN: { case P_WRITELN: {
if (buffer) { if (buffer) {
rc = fprintf(fp, "%s%s%s\n", rc = fprintf(fp, "%s\n", buffer);
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[37m" : ""),
buffer,
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[0m" : ""));
} else { } else {
rc = fprintf(fp, "\n"); rc = fprintf(fp, "\n");
} }
} break; } break;
case P_WRITE: if (buffer) { case P_WRITE: if (buffer) {
rc = fprintf(fp, "%s%s%s", rc = fprintf(fp, "%s", buffer);
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[37m" : ""),
buffer,
((PHPDBG_G(flags) & PHPDBG_IS_COLOURED) ? "\033[0m" : ""));
} break; } break;
/* no formatting on logging output */ /* no formatting on logging output */
@ -218,17 +226,74 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, ..
return rc; return rc;
} /* }}} */ } /* }}} */
PHPDBG_API const phpdbg_color_t* phpdbg_get_color(const char *name, size_t name_length) /* {{{ */ PHPDBG_API const phpdbg_color_t* phpdbg_get_color(const char *name, size_t name_length TSRMLS_DC) /* {{{ */
{ {
const phpdbg_color_t *color = colors; const phpdbg_color_t *color = colors;
while (color && color->name) { while (color && color->name) {
if (name_length == color->name_length && if (name_length == color->name_length &&
memcmp(name, color->name, name_length) == SUCCESS) { memcmp(name, color->name, name_length) == SUCCESS) {
phpdbg_debug(
"phpdbg_get_color(%s, %lu): %s", name, name_length, color->code);
return color; return color;
} }
++color; ++color;
} }
phpdbg_debug(
"phpdbg_get_color(%s, %lu): failed", name, name_length);
return NULL; return NULL;
} /* }}} */ } /* }}} */
PHPDBG_API void phpdbg_set_color(int element, const phpdbg_color_t *color TSRMLS_DC) /* {{{ */
{
PHPDBG_G(colors)[element] = color;
} /* }}} */
PHPDBG_API void phpdbg_set_color_ex(int element, const char *name, size_t name_length TSRMLS_DC) /* {{{ */
{
const phpdbg_color_t *color = phpdbg_get_color(name, name_length TSRMLS_CC);
if (color) {
phpdbg_set_color(element, color TSRMLS_CC);
} else PHPDBG_G(colors)[element] = colors;
} /* }}} */
PHPDBG_API void phpdbg_set_prompt(const char *prompt TSRMLS_DC) /* {{{ */
{
/* free formatted prompt */
if (PHPDBG_G(prompt)[1]) {
free(PHPDBG_G(prompt)[1]);
PHPDBG_G(prompt)[1] = NULL;
}
/* free old prompt */
if (PHPDBG_G(prompt)[0]) {
free(PHPDBG_G(prompt)[0]);
PHPDBG_G(prompt)[0] = NULL;
}
/* copy new prompt */
PHPDBG_G(prompt)[0] = strdup(prompt);
} /* }}} */
PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */
{
/* find cached prompt */
if (PHPDBG_G(prompt)[1]) {
return PHPDBG_G(prompt)[1];
}
/* create cached prompt */
if ((PHPDBG_G(flags) & PHPDBG_IS_COLOURED)) {
asprintf(
&PHPDBG_G(prompt)[1], "\033[%sm%s\033[0m ",
PHPDBG_G(colors)[PHPDBG_COLOR_PROMPT]->code,
PHPDBG_G(prompt)[0]);
} else {
asprintf(
&PHPDBG_G(prompt)[1], "%s ",
PHPDBG_G(prompt)[0]);
}
return PHPDBG_G(prompt)[1];
} /* }}} */

View file

@ -20,21 +20,6 @@
#ifndef PHPDBG_UTILS_H #ifndef PHPDBG_UTILS_H
#define PHPDBG_UTILS_H #define PHPDBG_UTILS_H
/* {{{ color management */
#define PHPDBG_COLOR_LEN 12
#define PHPDBG_COLOR_D(color, code) \
{color, sizeof(color), code}
#define PHPDBG_COLOR_END \
{NULL, 0L, {0}}
typedef struct _phpdbg_color_t {
char *name;
size_t name_length;
const char code[PHPDBG_COLOR_LEN];
} phpdbg_color_t;
PHPDBG_API const phpdbg_color_t* phpdbg_get_color(const char *name, size_t name_length); /* }}} */
/** /**
* Input scan functions * Input scan functions
*/ */
@ -90,4 +75,31 @@ PHPDBG_API int phpdbg_print(int TSRMLS_DC, FILE*, const char*, ...) PHP_ATTRIBUT
/* {{{ For separation */ /* {{{ For separation */
#define SEPARATE "------------------------------------------------" /* }}} */ #define SEPARATE "------------------------------------------------" /* }}} */
/* {{{ Color Management */
#define PHPDBG_COLOR_LEN 12
#define PHPDBG_COLOR_D(color, code) \
{color, sizeof(color)-1, code}
#define PHPDBG_COLOR_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
typedef struct _phpdbg_color_t {
char *name;
size_t name_length;
const char code[PHPDBG_COLOR_LEN];
} phpdbg_color_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); /* }}} */
/* {{{ Prompt Management */
PHPDBG_API void phpdbg_set_prompt(const char* TSRMLS_DC);
PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D); /* }}} */
#endif /* PHPDBG_UTILS_H */ #endif /* PHPDBG_UTILS_H */