Patch php-5.4-readline-rl_bindy_key for Readline related Bug #61585
Patch version 2012-03-31 19:52 UTC
Return to Bug #61585 |
Download this patch
Patch Revisions:
Developer: osama.sororu@eformations.net
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 1054b0e..ea6ca1c 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -60,6 +60,12 @@ PHP_FUNCTION(readline_redisplay);
PHP_FUNCTION(readline_on_new_line);
static zval *_prepped_callback = NULL;
+#endif
+
+#if HAVE_LIBREADLINE
+PHP_FUNCTION(readline_bind_key_function);
+
+static HashTable _bind_key_functions_ht;
#endif
@@ -125,6 +131,14 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_on_new_line, 0)
ZEND_END_ARG_INFO()
#endif
+
+#if HAVE_LIBREADLINE
+ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_bind_key_function, 0, 0, 2)
+ ZEND_ARG_INFO(0, key)
+ ZEND_ARG_INFO(0, funcname)
+ZEND_END_ARG_INFO()
+#endif
+
/* }}} */
/* {{{ module stuff */
@@ -148,6 +162,9 @@ static const zend_function_entry php_readline_functions[] = {
#if HAVE_RL_ON_NEW_LINE
PHP_FE(readline_on_new_line, arginfo_readline_on_new_line)
#endif
+#if HAVE_LIBREADLINE
+ PHP_FE(readline_bind_key_function, arginfo_readline_bind_key_function)
+#endif
PHP_FE_END
};
@@ -170,6 +187,10 @@ ZEND_GET_MODULE(readline)
PHP_MINIT_FUNCTION(readline)
{
+#if HAVE_LIBREADLINE
+ zend_hash_init(&_bind_key_functions_ht, 255, NULL, ZVAL_PTR_DTOR, 1);
+#endif
+
using_history();
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
}
@@ -192,6 +213,9 @@ PHP_RSHUTDOWN_FUNCTION(readline)
_prepped_callback = 0;
}
#endif
+#if HAVE_LIBREADLINE
+ zend_hash_destroy(&_bind_key_functions_ht);
+#endif
return SUCCESS;
}
@@ -558,6 +582,9 @@ static void php_rl_callback_handler(char *the_line)
zval_dtor(&dummy);
}
+#endif
+
+#if HAVE_LIBREADLINE
/* {{{ 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)
@@ -626,6 +653,73 @@ PHP_FUNCTION(readline_redisplay)
}
/* }}} */
+/* {{{ proto bool readline_bind_key_function(long key, string funcname)
+ Readline rl_bind_key */
+
+static int _readline_bind_key_cb(int count, int key)
+{
+ zval *params[2];
+ TSRMLS_FETCH();
+
+ params[0]=_readline_long_zval(key);
+ params[1]=_readline_long_zval(count);
+
+ zval **_callback_func = NULL;
+ long _key = key;
+ int r = zend_hash_find(&_bind_key_functions_ht, (char *) &_key, sizeof(_key), (void **)&_callback_func);
+ if (r == -1)
+ return -1;
+
+ int _return_int = 0;
+ zval *_callback_return = NULL;
+ MAKE_STD_ZVAL(_callback_return);
+
+ if (call_user_function(CG(function_table), NULL, *_callback_func, _callback_return, 2, params TSRMLS_CC) == SUCCESS) {
+ _return_int = _callback_return->value.lval;
+ zval_dtor(_callback_return);
+ FREE_ZVAL(_callback_return);
+ }
+
+ return _return_int;
+}
+
+PHP_FUNCTION(readline_bind_key_function)
+{
+ long key;
+ zval *arg = NULL;
+ char *name = NULL;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l!z", &key, &arg)) {
+ RETURN_FALSE;
+ }
+
+ if (Z_TYPE_P(arg) == IS_NULL) {
+ zend_hash_del(&_bind_key_functions_ht, (char *)&key, sizeof(key));
+ rl_bind_key(key, rl_insert);
+ }
+ else {
+ if (!zend_is_callable(arg, 0, &name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name);
+ efree(name);
+ RETURN_FALSE;
+ }
+ efree(name);
+
+ zval *_temp_callback = NULL;
+ MAKE_STD_ZVAL(_temp_callback);
+ *_temp_callback = *arg;
+ zval_copy_ctor(_temp_callback);
+
+ zend_hash_add(&_bind_key_functions_ht, (char *)&key, sizeof(key), &_temp_callback, sizeof(zval *), NULL);
+
+ rl_bind_key(key, &_readline_bind_key_cb);
+ }
+
+ RETURN_TRUE;
+}
+
+/* }}} */
+
#endif
#if HAVE_RL_ON_NEW_LINE
@@ -639,7 +733,6 @@ PHP_FUNCTION(readline_on_new_line)
#endif
-
#endif /* HAVE_LIBREADLINE */
/*
|