summaryrefslogtreecommitdiff
path: root/sapi/cli/php_cli.c
diff options
context:
space:
mode:
authorJohannes Schlüter <johannes@php.net>2010-05-20 20:55:33 +0000
committerJohannes Schlüter <johannes@php.net>2010-05-20 20:55:33 +0000
commit61db5cf98a91916c23ae4adf3754b2ef94a4fbb2 (patch)
tree1e0527691b9773d5edf32340d653810dd1d276a4 /sapi/cli/php_cli.c
parent31f62dbc72f5d2c2670a1e3646a4bf2e62f0321d (diff)
downloadphp-git-61db5cf98a91916c23ae4adf3754b2ef94a4fbb2.tar.gz
- Improved CLI Interactive readline shell (Johannes)
. Added cli.pager ini setting to set a pager for output. . Added cli.prompt ini settingto configure the shell prompt. . Added shortcut #inisetting=value to change ini settings at run-time. . Don't terminate shell on fatal errors. A pager can be a an shell command which will receive the command output on its STDIN channel php > #cli.pager=less php > phpinfo(); (output will appear in the pager) php > #cli.pager=grep -i readline php > phpcredits(); Readline => Thies C. Arntzen php > #cli.pager= (output appears again direct on the terminal) A prompt can contain a few escape sequences like php > #cli.prompt=\e[032m\v \e[031m\b \e[34m\> \e[0m 5.3.99-dev php > //Colorful prompt with version number A prompt can also contaian PHP code in backticks php > #cli.prompt=`echo gethostname();` \b \> guybrush php >
Diffstat (limited to 'sapi/cli/php_cli.c')
-rw-r--r--sapi/cli/php_cli.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index 37564d1372..bf272b4400 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -132,6 +132,7 @@ static char *php_optarg = NULL;
static int php_optind = 1;
#if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
static char php_last_char = '\0';
+static FILE *pager_pipe = NULL;
#endif
static const opt_struct OPTIONS[] = {
@@ -258,7 +259,23 @@ static inline size_t sapi_cli_single_write(const char *str, uint str_length TSRM
{
#ifdef PHP_WRITE_STDOUT
long ret;
+#endif
+
+#if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
+ if (CLIR_G(prompt_str)) {
+ smart_str_appendl(CLIR_G(prompt_str), str, str_length);
+ return str_length;
+ }
+
+ if (CLIR_G(pager) && *CLIR_G(pager) && !pager_pipe) {
+ pager_pipe = VCWD_POPEN(CLIR_G(pager), "w");
+ }
+ if (pager_pipe) {
+ return fwrite(str, 1, MIN(str_length, 16384), pager_pipe);
+ }
+#endif
+#ifdef PHP_WRITE_STDOUT
do {
ret = write(STDOUT_FILENO, str, str_length);
} while (ret <= 0 && errno == EAGAIN && sapi_cli_select(STDOUT_FILENO TSRMLS_CC));
@@ -401,7 +418,11 @@ static void sapi_cli_send_header(sapi_header_struct *sapi_header, void *server_c
static int php_cli_startup(sapi_module_struct *sapi_module) /* {{{ */
{
+#if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
+ if (php_module_startup(sapi_module, &cli_readline_module_entry, 1)==FAILURE) {
+#else
if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
+#endif
return FAILURE;
}
return SUCCESS;
@@ -1124,7 +1145,7 @@ int main(int argc, char *argv[])
char *line;
size_t size = 4096, pos = 0, len;
char *code = emalloc(size);
- char *prompt = "php > ";
+ char *prompt = cli_get_prompt("php", '>' TSRMLS_CC);
char *history_file;
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
@@ -1158,6 +1179,27 @@ int main(int argc, char *argv[])
}
len = strlen(line);
+
+ if (line[0] == '#') {
+ char *param = strstr(&line[1], "=");
+ if (param) {
+ char *cmd;
+ uint cmd_len;
+ param++;
+ cmd_len = param - &line[1] - 1;
+ cmd = estrndup(&line[1], cmd_len);
+
+ zend_alter_ini_entry_ex(cmd, cmd_len + 1, param, strlen(param), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
+ efree(cmd);
+ add_history(line);
+
+ efree(prompt);
+ /* TODO: This might be wrong! */
+ prompt = cli_get_prompt("php", '>' TSRMLS_CC);
+ continue;
+ }
+ }
+
if (pos + len + 2 > size) {
size = pos + len + 2;
code = erealloc(code, size);
@@ -1172,15 +1214,19 @@ int main(int argc, char *argv[])
}
free(line);
+ efree(prompt);
if (!cli_is_valid_code(code, pos, &prompt TSRMLS_CC)) {
continue;
}
- zend_eval_stringl(code, pos, NULL, "php shell code" TSRMLS_CC);
+ zend_try {
+ zend_eval_stringl(code, pos, NULL, "php shell code" TSRMLS_CC);
+ } zend_end_try();
+
pos = 0;
- if (php_last_char != '\0' && php_last_char != '\n') {
+ if (!pager_pipe && php_last_char != '\0' && php_last_char != '\n') {
sapi_cli_single_write("\n", 1 TSRMLS_CC);
}
@@ -1188,11 +1234,17 @@ int main(int argc, char *argv[])
zend_exception_error(EG(exception), E_WARNING TSRMLS_CC);
}
+ if (pager_pipe) {
+ fclose(pager_pipe);
+ pager_pipe = NULL;
+ }
+
php_last_char = '\0';
}
write_history(history_file);
free(history_file);
efree(code);
+ efree(prompt);
exit_status = EG(exit_status);
break;
}