summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2004-08-24 12:52:07 +0000
committerWez Furlong <wez@php.net>2004-08-24 12:52:07 +0000
commitbbd6dec20c341b9a9468ab9305b0731da782d5bb (patch)
tree3ef90f179c191d9c328217c613ee9f8e1eb5c731 /ext
parent0bfb0fad9227819c32fdd73dd0735a8a3fe93a15 (diff)
downloadphp-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.m47
-rw-r--r--ext/readline/readline.c98
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(&params[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 */
/*