diff options
| author | Wez Furlong <wez@php.net> | 2004-08-24 12:52:07 +0000 |
|---|---|---|
| committer | Wez Furlong <wez@php.net> | 2004-08-24 12:52:07 +0000 |
| commit | bbd6dec20c341b9a9468ab9305b0731da782d5bb (patch) | |
| tree | 3ef90f179c191d9c328217c613ee9f8e1eb5c731 /ext | |
| parent | 0bfb0fad9227819c32fdd73dd0735a8a3fe93a15 (diff) | |
| download | php-git-bbd6dec20c341b9a9468ab9305b0731da782d5bb.tar.gz | |
Add support for the readline callback interface, allowing you to interleave
IO and user input. Sample script:
<?php
dl("readline.so");
function handle_user_input($line)
{
echo "You typed: '$line'\n";
if ($line == 'exit')
exit;
}
readline_callback_handler_install('type! > ', 'handle_user_input');
while (true) {
$n = stream_select($r = array(STDIN), $w = null, $e = null, null);
if ($n && in_array(STDIN, $r)) {
readline_callback_read_char();
}
}
Diffstat (limited to 'ext')
| -rw-r--r-- | ext/readline/config.m4 | 7 | ||||
| -rw-r--r-- | ext/readline/readline.c | 98 |
2 files changed, 105 insertions, 0 deletions
diff --git a/ext/readline/config.m4 b/ext/readline/config.m4 index b313bd550c..8ed89206e8 100644 --- a/ext/readline/config.m4 +++ b/ext/readline/config.m4 @@ -41,6 +41,13 @@ if test "$PHP_READLINE" != "no"; then -L$READLINE_DIR/lib $PHP_READLINE_LIBS ]) + PHP_CHECK_LIBRARY(readline, rl_callback_read_char, + [ + AC_DEFINE(HAVE_RL_CALLBACK_READ_CHAR, 1, [ ]) + ],[],[ + -L$READLINE_DIR/lib $PHP_READLINE_LIBS + ]) + PHP_CHECK_LIBRARY(history, add_history, [ PHP_ADD_LIBRARY_WITH_PATH(history, $READLINE_DIR/lib, READLINE_SHARED_LIBADD) diff --git a/ext/readline/readline.c b/ext/readline/readline.c index 44a0808165..3084b8abd7 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -45,6 +45,15 @@ PHP_FUNCTION(readline_read_history); PHP_FUNCTION(readline_write_history); PHP_FUNCTION(readline_completion_function); +#if HAVE_RL_CALLBACK_READ_CHAR +PHP_FUNCTION(readline_callback_handler_install); +PHP_FUNCTION(readline_callback_read_char); +PHP_FUNCTION(readline_callback_handler_remove); + +static zval *_prepped_callback = NULL; + +#endif + static char *_readline_completion = NULL; static zval _readline_array; @@ -65,6 +74,11 @@ static zend_function_entry php_readline_functions[] = { PHP_FE(readline_read_history, NULL) PHP_FE(readline_write_history, NULL) PHP_FE(readline_completion_function,NULL) +#if HAVE_RL_CALLBACK_READ_CHAR + PHP_FE(readline_callback_handler_install, NULL) + PHP_FE(readline_callback_read_char, NULL) + PHP_FE(readline_callback_handler_remove, NULL) +#endif {NULL, NULL, NULL} }; @@ -95,6 +109,13 @@ PHP_RSHUTDOWN_FUNCTION(readline) { if (_readline_completion) efree(_readline_completion); +#if HAVE_RL_CALLBACK_READ_CHAR + if (_prepped_callback) { + rl_callback_handler_remove(); + FREE_ZVAL(_prepped_callback); + _prepped_callback = 0; + } +#endif return SUCCESS; } @@ -429,6 +450,83 @@ PHP_FUNCTION(readline_completion_function) /* }}} */ +#if HAVE_RL_CALLBACK_READ_CHAR + +static void php_rl_callback_handler(char *the_line) +{ + zval *params[1]; + zval dummy; + TSRMLS_FETCH(); + + ZVAL_NULL(&dummy); + + params[0] = _readline_string_zval(the_line); + + call_user_function(CG(function_table), NULL, _prepped_callback, &dummy, 1, params TSRMLS_CC); + + zval_ptr_dtor(¶ms[0]); + zval_dtor(&dummy); +} + +/* {{{ proto void readline_callback_handler_install(string prompt, mixed callback) + Initializes the readline callback interface and terminal, prints the prompt and returns immediately */ +PHP_FUNCTION(readline_callback_handler_install) +{ + zval *callback; + char *name = NULL; + char *prompt; + int prompt_len; + + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &prompt, &prompt_len, &callback)) { + return; + } + + if (!zend_is_callable(callback, 0, &name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name); + RETURN_FALSE; + } + + if (_prepped_callback) { + rl_callback_handler_remove(); + FREE_ZVAL(_prepped_callback); + } + + MAKE_STD_ZVAL(_prepped_callback); + *_prepped_callback = *callback; + zval_copy_ctor(_prepped_callback); + + rl_callback_handler_install(prompt, php_rl_callback_handler); + + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void readline_callback_read_char() + Informs the readline callback interface that a character is ready for input */ +PHP_FUNCTION(readline_callback_read_char) +{ + if (_prepped_callback) { + rl_callback_read_char(); + } +} +/* }}} */ + +/* {{{ proto bool readline_callback_handler_remove() + Removes a previously installed callback handler and restores terminal settings */ +PHP_FUNCTION(readline_callback_handler_remove) +{ + if (_prepped_callback) { + rl_callback_handler_remove(); + FREE_ZVAL(_prepped_callback); + _prepped_callback = 0; + RETURN_TRUE; + } + RETURN_FALSE; +} +/* }}} */ +#endif + + #endif /* HAVE_LIBREADLINE */ /* |
