php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #61585
Patch php-5.4-readline-rl_bindy_key revision 2012-03-31 19:52 UTC by osama dot sororu at eformations dot net

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 */
 
 /*
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 16:01:31 2024 UTC