php-src/ext/readline/readline.c

645 lines
16 KiB
C
Raw Normal View History

/*
+----------------------------------------------------------------------+
2014-09-19 16:33:14 +00:00
| PHP Version 7 |
+----------------------------------------------------------------------+
2015-01-15 15:27:30 +00:00
| Copyright (c) 1997-2015 The PHP Group |
+----------------------------------------------------------------------+
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
2006-01-01 12:51:34 +00:00
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
2002-02-28 08:29:35 +00:00
| Author: Thies C. Arntzen <thies@thieso.net> |
+----------------------------------------------------------------------+
*/
/* $Id$ */
/* {{{ includes & prototypes */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "php_readline.h"
#include "readline_cli.h"
#if HAVE_LIBREADLINE || HAVE_LIBEDIT
#ifndef HAVE_RL_COMPLETION_MATCHES
#define rl_completion_matches completion_matches
#endif
#ifdef HAVE_LIBEDIT
#include <editline/readline.h>
#else
#include <readline/readline.h>
#include <readline/history.h>
#endif
PHP_FUNCTION(readline);
PHP_FUNCTION(readline_add_history);
PHP_FUNCTION(readline_info);
PHP_FUNCTION(readline_clear_history);
#ifndef HAVE_LIBEDIT
PHP_FUNCTION(readline_list_history);
#endif
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);
PHP_FUNCTION(readline_redisplay);
PHP_FUNCTION(readline_on_new_line);
2014-05-18 11:49:35 +00:00
static zval _prepped_callback;
#endif
2014-05-18 11:49:35 +00:00
static zval _readline_completion;
static zval _readline_array;
PHP_MINIT_FUNCTION(readline);
PHP_MSHUTDOWN_FUNCTION(readline);
PHP_RSHUTDOWN_FUNCTION(readline);
PHP_MINFO_FUNCTION(readline);
/* }}} */
2008-07-14 17:50:47 +00:00
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline, 0, 0, 0)
ZEND_ARG_INFO(0, prompt)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_info, 0, 0, 0)
ZEND_ARG_INFO(0, varname)
ZEND_ARG_INFO(0, newvalue)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_add_history, 0, 0, 1)
ZEND_ARG_INFO(0, prompt)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_clear_history, 0)
ZEND_END_ARG_INFO()
#ifndef HAVE_LIBEDIT
ZEND_BEGIN_ARG_INFO(arginfo_readline_list_history, 0)
ZEND_END_ARG_INFO()
#endif
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_read_history, 0, 0, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_write_history, 0, 0, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_completion_function, 0, 0, 1)
ZEND_ARG_INFO(0, funcname)
ZEND_END_ARG_INFO()
#if HAVE_RL_CALLBACK_READ_CHAR
ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_callback_handler_install, 0, 0, 2)
ZEND_ARG_INFO(0, prompt)
ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_callback_read_char, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_callback_handler_remove, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_redisplay, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_on_new_line, 0)
ZEND_END_ARG_INFO()
#endif
/* }}} */
/* {{{ module stuff */
static const zend_function_entry php_readline_functions[] = {
2008-07-14 17:50:47 +00:00
PHP_FE(readline, arginfo_readline)
PHP_FE(readline_info, arginfo_readline_info)
PHP_FE(readline_add_history, arginfo_readline_add_history)
PHP_FE(readline_clear_history, arginfo_readline_clear_history)
#ifndef HAVE_LIBEDIT
2008-07-14 17:50:47 +00:00
PHP_FE(readline_list_history, arginfo_readline_list_history)
#endif
2008-07-14 17:50:47 +00:00
PHP_FE(readline_read_history, arginfo_readline_read_history)
PHP_FE(readline_write_history, arginfo_readline_write_history)
PHP_FE(readline_completion_function,arginfo_readline_completion_function)
#if HAVE_RL_CALLBACK_READ_CHAR
2008-07-14 17:50:47 +00:00
PHP_FE(readline_callback_handler_install, arginfo_readline_callback_handler_install)
PHP_FE(readline_callback_read_char, arginfo_readline_callback_read_char)
PHP_FE(readline_callback_handler_remove, arginfo_readline_callback_handler_remove)
PHP_FE(readline_redisplay, arginfo_readline_redisplay)
#endif
#if HAVE_RL_ON_NEW_LINE
2008-07-14 17:50:47 +00:00
PHP_FE(readline_on_new_line, arginfo_readline_on_new_line)
#endif
2011-07-25 11:35:02 +00:00
PHP_FE_END
};
2015-01-03 09:22:58 +00:00
zend_module_entry readline_module_entry = {
STANDARD_MODULE_HEADER,
2015-01-03 09:22:58 +00:00
"readline",
php_readline_functions,
PHP_MINIT(readline),
PHP_MSHUTDOWN(readline),
NULL,
PHP_RSHUTDOWN(readline),
2015-01-03 09:22:58 +00:00
PHP_MINFO(readline),
PHP_READLINE_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_READLINE
ZEND_GET_MODULE(readline)
#endif
PHP_MINIT_FUNCTION(readline)
{
#if HAVE_LIBREADLINE
/* libedit don't need this call which set the tty in cooked mode */
2014-05-18 11:49:35 +00:00
using_history();
#endif
ZVAL_UNDEF(&_readline_completion);
#if HAVE_RL_CALLBACK_READ_CHAR
ZVAL_UNDEF(&_prepped_callback);
#endif
2014-05-18 11:49:35 +00:00
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
}
PHP_MSHUTDOWN_FUNCTION(readline)
{
return PHP_MSHUTDOWN(cli_readline)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
}
PHP_RSHUTDOWN_FUNCTION(readline)
{
2014-05-18 11:49:35 +00:00
zval_dtor(&_readline_completion);
ZVAL_UNDEF(&_readline_completion);
#if HAVE_RL_CALLBACK_READ_CHAR
2014-05-18 11:49:35 +00:00
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
zval_ptr_dtor(&_prepped_callback);
2014-05-18 11:49:35 +00:00
ZVAL_UNDEF(&_prepped_callback);
}
#endif
return SUCCESS;
}
PHP_MINFO_FUNCTION(readline)
{
PHP_MINFO(cli_readline)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto string readline([string prompt])
2000-02-24 17:23:04 +00:00
Reads a line */
PHP_FUNCTION(readline)
{
char *prompt = NULL;
size_t prompt_len;
char *result;
2000-08-24 15:29:50 +00:00
2014-12-13 22:06:14 +00:00
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &prompt, &prompt_len)) {
RETURN_FALSE;
}
result = readline(prompt);
if (! result) {
RETURN_FALSE;
} else {
2014-05-18 11:49:35 +00:00
RETVAL_STRING(result);
free(result);
}
}
/* }}} */
#define SAFE_STRING(s) ((s)?(char*)(s):"")
2015-01-03 09:22:58 +00:00
/* {{{ proto mixed readline_info([string varname [, string newvalue]])
2008-06-25 15:06:58 +00:00
Gets/sets various internal readline variables. */
PHP_FUNCTION(readline_info)
{
2009-01-16 00:07:03 +00:00
char *what = NULL;
2014-05-18 11:49:35 +00:00
zval *value = NULL;
size_t what_len, oldval;
1999-10-25 08:23:54 +00:00
char *oldstr;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sz", &what, &what_len, &value) == FAILURE) {
2008-06-25 15:06:58 +00:00
return;
}
1999-10-25 08:23:54 +00:00
2009-01-22 14:40:20 +00:00
if (!what) {
1999-10-25 08:23:54 +00:00
array_init(return_value);
2014-04-15 11:40:40 +00:00
add_assoc_string(return_value,"line_buffer",SAFE_STRING(rl_line_buffer));
2014-08-25 17:24:55 +00:00
add_assoc_long(return_value,"point",rl_point);
add_assoc_long(return_value,"end",rl_end);
#ifdef HAVE_LIBREADLINE
2014-08-25 17:24:55 +00:00
add_assoc_long(return_value,"mark",rl_mark);
add_assoc_long(return_value,"done",rl_done);
add_assoc_long(return_value,"pending_input",rl_pending_input);
2014-04-15 11:40:40 +00:00
add_assoc_string(return_value,"prompt",SAFE_STRING(rl_prompt));
add_assoc_string(return_value,"terminal_name",(char *)SAFE_STRING(rl_terminal_name));
#endif
1999-10-25 08:23:54 +00:00
#if HAVE_ERASE_EMPTY_LINE
2014-08-25 17:24:55 +00:00
add_assoc_long(return_value,"erase_empty_line",rl_erase_empty_line);
1999-10-25 08:23:54 +00:00
#endif
2014-04-15 11:40:40 +00:00
add_assoc_string(return_value,"library_version",(char *)SAFE_STRING(rl_library_version));
add_assoc_string(return_value,"readline_name",(char *)SAFE_STRING(rl_readline_name));
2014-08-25 17:24:55 +00:00
add_assoc_long(return_value,"attempted_completion_over",rl_attempted_completion_over);
1999-10-25 08:23:54 +00:00
} else {
2008-06-25 15:06:58 +00:00
if (!strcasecmp(what,"line_buffer")) {
1999-10-25 08:23:54 +00:00
oldstr = rl_line_buffer;
2009-01-16 00:07:03 +00:00
if (value) {
1999-10-25 08:23:54 +00:00
/* XXX if (rl_line_buffer) free(rl_line_buffer); */
convert_to_string_ex(value);
2014-05-18 11:49:35 +00:00
rl_line_buffer = strdup(Z_STRVAL_P(value));
1999-10-25 08:23:54 +00:00
}
2014-05-18 11:49:35 +00:00
RETVAL_STRING(SAFE_STRING(oldstr));
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "point")) {
2014-08-25 17:24:55 +00:00
RETVAL_LONG(rl_point);
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "end")) {
2014-08-25 17:24:55 +00:00
RETVAL_LONG(rl_end);
#ifdef HAVE_LIBREADLINE
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "mark")) {
2014-08-25 17:24:55 +00:00
RETVAL_LONG(rl_mark);
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "done")) {
1999-10-25 08:23:54 +00:00
oldval = rl_done;
2009-01-16 00:07:03 +00:00
if (value) {
2014-08-25 19:51:49 +00:00
convert_to_long_ex(value);
2014-08-25 17:24:55 +00:00
rl_done = Z_LVAL_P(value);
1999-10-25 08:23:54 +00:00
}
2014-08-25 17:24:55 +00:00
RETVAL_LONG(oldval);
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "pending_input")) {
1999-10-25 08:23:54 +00:00
oldval = rl_pending_input;
2009-01-16 00:07:03 +00:00
if (value) {
1999-10-25 08:23:54 +00:00
convert_to_string_ex(value);
2014-05-18 11:49:35 +00:00
rl_pending_input = Z_STRVAL_P(value)[0];
1999-10-25 08:23:54 +00:00
}
2014-08-25 17:24:55 +00:00
RETVAL_LONG(oldval);
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "prompt")) {
2014-05-18 11:49:35 +00:00
RETVAL_STRING(SAFE_STRING(rl_prompt));
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "terminal_name")) {
2014-05-18 11:49:35 +00:00
RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name));
#endif
1999-10-25 08:23:54 +00:00
#if HAVE_ERASE_EMPTY_LINE
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "erase_empty_line")) {
1999-10-25 08:23:54 +00:00
oldval = rl_erase_empty_line;
2009-01-16 00:07:03 +00:00
if (value) {
2014-08-25 19:51:49 +00:00
convert_to_long_ex(value);
2014-08-25 17:24:55 +00:00
rl_erase_empty_line = Z_LVAL_PP(value);
1999-10-25 08:23:54 +00:00
}
2014-08-25 17:24:55 +00:00
RETVAL_LONG(oldval);
1999-10-25 08:23:54 +00:00
#endif
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what,"library_version")) {
2014-05-18 11:49:35 +00:00
RETVAL_STRING((char *)SAFE_STRING(rl_library_version));
2008-06-25 15:06:58 +00:00
} else if (!strcasecmp(what, "readline_name")) {
oldstr = (char*)rl_readline_name;
2009-01-16 00:07:03 +00:00
if (value) {
1999-10-25 08:23:54 +00:00
/* XXX if (rl_readline_name) free(rl_readline_name); */
convert_to_string_ex(value);
2014-05-18 11:49:35 +00:00
rl_readline_name = strdup(Z_STRVAL_P(value));;
1999-10-25 08:23:54 +00:00
}
2014-05-18 11:49:35 +00:00
RETVAL_STRING(SAFE_STRING(oldstr));
} else if (!strcasecmp(what, "attempted_completion_over")) {
oldval = rl_attempted_completion_over;
if (value) {
2014-08-25 19:51:49 +00:00
convert_to_long_ex(value);
2014-08-25 17:24:55 +00:00
rl_attempted_completion_over = Z_LVAL_P(value);
}
2014-08-25 17:24:55 +00:00
RETVAL_LONG(oldval);
}
1999-10-25 08:23:54 +00:00
}
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto bool readline_add_history(string prompt)
2000-02-24 17:23:04 +00:00
Adds a line to the history */
PHP_FUNCTION(readline_add_history)
{
2008-06-25 15:06:58 +00:00
char *arg;
size_t arg_len;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
2008-06-25 15:06:58 +00:00
return;
}
2008-06-25 15:06:58 +00:00
add_history(arg);
RETURN_TRUE;
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto bool readline_clear_history(void)
2000-02-24 17:23:04 +00:00
Clears the history */
PHP_FUNCTION(readline_clear_history)
{
2008-06-25 15:06:58 +00:00
if (zend_parse_parameters_none() == FAILURE) {
return;
}
#if HAVE_LIBEDIT
/* clear_history is the only function where rl_initialize
is not call to ensure correct allocation */
using_history();
#endif
clear_history();
RETURN_TRUE;
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto array readline_list_history(void)
2000-02-24 17:23:04 +00:00
Lists the history */
#ifndef HAVE_LIBEDIT
PHP_FUNCTION(readline_list_history)
{
HIST_ENTRY **history;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
2015-01-03 09:22:58 +00:00
history = history_list();
2015-01-03 09:22:58 +00:00
array_init(return_value);
if (history) {
int i;
for (i = 0; history[i]; i++) {
2014-04-15 11:40:40 +00:00
add_next_index_string(return_value,history[i]->line);
}
}
}
#endif
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto bool readline_read_history([string filename])
2000-02-24 17:23:04 +00:00
Reads the history */
PHP_FUNCTION(readline_read_history)
{
2008-06-25 15:06:58 +00:00
char *arg = NULL;
size_t arg_len;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p", &arg, &arg_len) == FAILURE) {
2008-06-25 15:06:58 +00:00
return;
}
if (arg && php_check_open_basedir(arg)) {
RETURN_FALSE;
}
/* XXX from & to NYI */
2008-06-25 15:06:58 +00:00
if (read_history(arg)) {
/* If filename is NULL, then read from `~/.history' */
RETURN_FALSE;
} else {
RETURN_TRUE;
}
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto bool readline_write_history([string filename])
2000-02-24 17:23:04 +00:00
Writes the history */
PHP_FUNCTION(readline_write_history)
{
2008-06-25 15:06:58 +00:00
char *arg = NULL;
size_t arg_len;
2014-12-13 22:06:14 +00:00
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p", &arg, &arg_len) == FAILURE) {
2008-06-25 15:06:58 +00:00
return;
}
if (arg && php_check_open_basedir(arg)) {
RETURN_FALSE;
}
2008-06-25 15:06:58 +00:00
if (write_history(arg)) {
RETURN_FALSE;
} else {
RETURN_TRUE;
}
}
/* }}} */
2015-01-03 09:22:58 +00:00
/* {{{ proto bool readline_completion_function(string funcname)
2000-02-24 17:23:04 +00:00
Readline completion function? */
2006-09-04 18:59:01 +00:00
static char *_readline_command_generator(const char *text, int state)
{
HashTable *myht = Z_ARRVAL(_readline_array);
2014-05-18 11:49:35 +00:00
zval *entry;
2015-01-03 09:22:58 +00:00
2008-06-25 15:06:58 +00:00
if (!state) {
zend_hash_internal_pointer_reset(myht);
}
2015-01-03 09:22:58 +00:00
2014-05-18 11:49:35 +00:00
while ((entry = zend_hash_get_current_data(myht)) != NULL) {
zend_hash_move_forward(myht);
convert_to_string_ex(entry);
2014-05-18 11:49:35 +00:00
if (strncmp (Z_STRVAL_P(entry), text, strlen(text)) == 0) {
return (strdup(Z_STRVAL_P(entry)));
}
}
2005-02-04 00:21:50 +00:00
return NULL;
}
2014-05-18 11:49:35 +00:00
static void _readline_string_zval(zval *ret, const char *str)
{
if (str) {
2014-05-18 11:49:35 +00:00
ZVAL_STRING(ret, (char*)str);
} else {
ZVAL_NULL(ret);
}
}
2014-05-18 11:49:35 +00:00
static void _readline_long_zval(zval *ret, long l)
{
2014-08-25 17:24:55 +00:00
ZVAL_LONG(ret, l);
}
static char **_readline_completion_cb(const char *text, int start, int end)
2015-01-03 09:22:58 +00:00
{
2014-05-18 11:49:35 +00:00
zval params[3];
int i;
char **matches = NULL;
2014-05-18 11:49:35 +00:00
_readline_string_zval(&params[0], text);
_readline_long_zval(&params[1], start);
_readline_long_zval(&params[2], end);
2014-12-13 22:06:14 +00:00
if (call_user_function(CG(function_table), NULL, &_readline_completion, &_readline_array, 3, params) == SUCCESS) {
if (Z_TYPE(_readline_array) == IS_ARRAY) {
2005-02-04 00:21:50 +00:00
if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) {
matches = rl_completion_matches(text,_readline_command_generator);
2005-02-04 00:21:50 +00:00
} else {
matches = malloc(sizeof(char *) * 2);
if (!matches) {
return NULL;
}
2005-02-04 00:21:50 +00:00
matches[0] = strdup("");
matches[1] = '\0';
}
}
}
2015-01-03 09:22:58 +00:00
for (i = 0; i < 3; i++) {
zval_ptr_dtor(&params[i]);
}
zval_dtor(&_readline_array);
2015-01-03 09:22:58 +00:00
return matches;
}
PHP_FUNCTION(readline_completion_function)
{
zval *arg = NULL;
2014-05-18 11:49:35 +00:00
zend_string *name = NULL;
2014-12-13 22:06:14 +00:00
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg)) {
RETURN_FALSE;
}
2014-12-13 22:06:14 +00:00
if (!zend_is_callable(arg, 0, &name)) {
php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
2014-08-25 17:24:55 +00:00
zend_string_release(name);
RETURN_FALSE;
}
2014-08-25 17:24:55 +00:00
zend_string_release(name);
2014-05-18 11:49:35 +00:00
zval_dtor(&_readline_completion);
ZVAL_DUP(&_readline_completion, arg);
rl_attempted_completion_function = _readline_completion_cb;
if (rl_attempted_completion_function == NULL) {
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
#if HAVE_RL_CALLBACK_READ_CHAR
static void php_rl_callback_handler(char *the_line)
{
2014-05-18 11:49:35 +00:00
zval params[1];
zval dummy;
ZVAL_NULL(&dummy);
2014-05-18 11:49:35 +00:00
_readline_string_zval(&params[0], the_line);
2014-12-13 22:06:14 +00:00
call_user_function(CG(function_table), NULL, &_prepped_callback, &dummy, 1, params);
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;
2014-05-18 11:49:35 +00:00
zend_string *name = NULL;
char *prompt;
size_t prompt_len;
2014-12-13 22:06:14 +00:00
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &prompt, &prompt_len, &callback)) {
return;
}
2014-12-13 22:06:14 +00:00
if (!zend_is_callable(callback, 0, &name)) {
php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
2014-08-25 17:24:55 +00:00
zend_string_release(name);
RETURN_FALSE;
}
2014-08-25 17:24:55 +00:00
zend_string_release(name);
2014-05-18 11:49:35 +00:00
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
2014-05-18 11:49:35 +00:00
zval_dtor(&_prepped_callback);
}
2014-05-18 11:49:35 +00:00
ZVAL_DUP(&_prepped_callback, 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)
{
2014-05-18 11:49:35 +00:00
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
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)
{
2014-05-18 11:49:35 +00:00
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
2014-05-18 11:49:35 +00:00
zval_dtor(&_prepped_callback);
ZVAL_UNDEF(&_prepped_callback);
RETURN_TRUE;
}
RETURN_FALSE;
}
/* }}} */
/* {{{ proto void readline_redisplay(void)
Ask readline to redraw the display */
PHP_FUNCTION(readline_redisplay)
{
rl_redisplay();
}
/* }}} */
#endif
#if HAVE_RL_ON_NEW_LINE
/* {{{ proto void readline_on_new_line(void)
Inform readline that the cursor has moved to a new line */
PHP_FUNCTION(readline_on_new_line)
{
rl_on_new_line();
}
/* }}} */
#endif
#endif /* HAVE_LIBREADLINE */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/