summaryrefslogtreecommitdiff
path: root/ext/readline
diff options
context:
space:
mode:
Diffstat (limited to 'ext/readline')
-rw-r--r--ext/readline/README.libedit4
-rw-r--r--ext/readline/config.m447
-rw-r--r--ext/readline/config.w321
-rw-r--r--ext/readline/php_readline.h7
-rw-r--r--ext/readline/readline.c90
-rw-r--r--ext/readline/readline_cli.c48
-rw-r--r--ext/readline/readline_cli.h2
-rw-r--r--ext/readline/tests/readline_basic.phpt17
-rw-r--r--ext/readline/tests/readline_read_history_001.phpt4
-rw-r--r--ext/readline/tests/readline_read_history_error_001.phpt2
-rw-r--r--ext/readline/tests/readline_without_input.phpt15
11 files changed, 150 insertions, 87 deletions
diff --git a/ext/readline/README.libedit b/ext/readline/README.libedit
deleted file mode 100644
index a19371056e..0000000000
--- a/ext/readline/README.libedit
+++ /dev/null
@@ -1,4 +0,0 @@
-This library can be built with libedit - non-GPL drop-in readline replacement.
-Libedit can be obtained from http://sourceforge.net/projects/libedit/
-It is taken from NetBSD (http://www.netbsd.org/) CVS repository and modified
-to work as stand-alone library.
diff --git a/ext/readline/config.m4 b/ext/readline/config.m4
index 0395835931..ed205764f2 100644
--- a/ext/readline/config.m4
+++ b/ext/readline/config.m4
@@ -1,13 +1,16 @@
-dnl config.m4 for extension readline
-
-PHP_ARG_WITH(libedit,for libedit readline replacement,
-[ --with-libedit[=DIR] Include libedit readline replacement (CLI/CGI only)])
+PHP_ARG_WITH([libedit],
+ [for libedit readline replacement],
+ [AS_HELP_STRING([--with-libedit],
+ [Include libedit readline replacement (CLI/CGI only)])])
if test "$PHP_LIBEDIT" = "no"; then
- PHP_ARG_WITH(readline,for readline support,
- [ --with-readline[=DIR] Include readline support (CLI/CGI only)])
+ PHP_ARG_WITH([readline],
+ [for readline support],
+ [AS_HELP_STRING([[--with-readline[=DIR]]],
+ [Include readline support (CLI/CGI only)])])
else
- dnl "register" the --with-readline option to preven invalid "unknown configure option" warning
+ dnl "register" the --with-readline option to prevent invalid "unknown
+ dnl configure option" warning
php_with_readline=no
fi
@@ -72,19 +75,17 @@ if test "$PHP_READLINE" && test "$PHP_READLINE" != "no"; then
-L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
])
+ AC_DEFINE(HAVE_HISTORY_LIST, 1, [ ])
AC_DEFINE(HAVE_LIBREADLINE, 1, [ ])
elif test "$PHP_LIBEDIT" != "no"; then
-
- for i in $PHP_LIBEDIT /usr/local /usr; do
- test -f $i/include/editline/readline.h && LIBEDIT_DIR=$i && break
- done
-
- if test -z "$LIBEDIT_DIR"; then
- AC_MSG_ERROR(Please reinstall libedit - I cannot find readline.h)
+ if test "$PHP_LIBEDIT" != "yes"; then
+ AC_MSG_WARN([libedit directory ignored, rely on pkg-config])
fi
- PHP_ADD_INCLUDE($LIBEDIT_DIR/include)
+ PKG_CHECK_MODULES([EDIT], [libedit])
+ PHP_EVAL_LIBLINE($EDIT_LIBS, READLINE_SHARED_LIBADD)
+ PHP_EVAL_INCLINE($EDIT_CFLAGS)
AC_CHECK_LIB(ncurses, tgetent,
[
@@ -98,32 +99,38 @@ elif test "$PHP_LIBEDIT" != "no"; then
PHP_CHECK_LIBRARY(edit, readline,
[
- PHP_ADD_LIBRARY_WITH_PATH(edit, $LIBEDIT_DIR/$PHP_LIBDIR, READLINE_SHARED_LIBADD)
], [
AC_MSG_ERROR(edit library required by readline not found)
], [
- -L$READLINE_DIR/$PHP_LIBDIR
+ $READLINE_SHARED_LIBADD
])
PHP_CHECK_LIBRARY(edit, rl_callback_read_char,
[
AC_DEFINE(HAVE_RL_CALLBACK_READ_CHAR, 1, [ ])
],[],[
- -L$READLINE_DIR/$PHP_LIBDIR
+ $READLINE_SHARED_LIBADD
])
PHP_CHECK_LIBRARY(edit, rl_on_new_line,
[
AC_DEFINE(HAVE_RL_ON_NEW_LINE, 1, [ ])
],[],[
- -L$READLINE_DIR/$PHP_LIBDIR
+ $READLINE_SHARED_LIBADD
])
PHP_CHECK_LIBRARY(edit, rl_completion_matches,
[
AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, [ ])
],[],[
- -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS
+ $READLINE_SHARED_LIBADD
+ ])
+
+ PHP_CHECK_LIBRARY(edit, history_list,
+ [
+ AC_DEFINE(HAVE_HISTORY_LIST, 1, [ ])
+ ],[],[
+ $READLINE_SHARED_LIBADD
])
AC_DEFINE(HAVE_LIBEDIT, 1, [ ])
diff --git a/ext/readline/config.w32 b/ext/readline/config.w32
index 4e9e89c964..8f3a2db61f 100644
--- a/ext/readline/config.w32
+++ b/ext/readline/config.w32
@@ -8,6 +8,7 @@ if (PHP_READLINE != "no") {
EXTENSION("readline", "readline.c readline_cli.c");
ADD_FLAG("CFLAGS_READLINE", "/D HAVE_LIBEDIT");
ADD_FLAG("CFLAGS_READLINE", "/D HAVE_RL_COMPLETION_MATCHES");
+ ADD_FLAG("CFLAGS_READLINE", "/D HAVE_HISTORY_LIST");
} else {
WARNING("readline not enabled; libraries and headers not found");
}
diff --git a/ext/readline/php_readline.h b/ext/readline/php_readline.h
index 8d7e5511b1..8d55228a7f 100644
--- a/ext/readline/php_readline.h
+++ b/ext/readline/php_readline.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2018 The PHP Group |
+ | Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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 |
@@ -20,11 +20,6 @@
#define PHP_READLINE_H
#if HAVE_LIBREADLINE || HAVE_LIBEDIT
-#ifndef PHP_WIN32
-#ifdef ZTS
-#warning Readline module will *NEVER* be thread-safe
-#endif
-#endif
extern zend_module_entry readline_module_entry;
#define phpext_readline_ptr &readline_module_entry
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 409212961f..b9435521ca 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2018 The PHP Group |
+ | Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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 |
@@ -43,7 +43,7 @@ PHP_FUNCTION(readline);
PHP_FUNCTION(readline_add_history);
PHP_FUNCTION(readline_info);
PHP_FUNCTION(readline_clear_history);
-#ifndef HAVE_LIBEDIT
+#ifdef HAVE_HISTORY_LIST
PHP_FUNCTION(readline_list_history);
#endif
PHP_FUNCTION(readline_read_history);
@@ -88,7 +88,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_readline_clear_history, 0)
ZEND_END_ARG_INFO()
-#ifndef HAVE_LIBEDIT
+#ifdef HAVE_HISTORY_LIST
ZEND_BEGIN_ARG_INFO(arginfo_readline_list_history, 0)
ZEND_END_ARG_INFO()
#endif
@@ -133,7 +133,7 @@ static const zend_function_entry php_readline_functions[] = {
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
+#ifdef HAVE_HISTORY_LIST
PHP_FE(readline_list_history, arginfo_readline_list_history)
#endif
PHP_FE(readline_read_history, arginfo_readline_read_history)
@@ -279,7 +279,9 @@ PHP_FUNCTION(readline_info)
oldstr = rl_line_buffer;
if (value) {
/* XXX if (rl_line_buffer) free(rl_line_buffer); */
- convert_to_string_ex(value);
+ if (!try_convert_to_string(value)) {
+ return;
+ }
rl_line_buffer = strdup(Z_STRVAL_P(value));
}
RETVAL_STRING(SAFE_STRING(oldstr));
@@ -302,7 +304,9 @@ PHP_FUNCTION(readline_info)
} else if (!strcasecmp(what, "pending_input")) {
oldval = rl_pending_input;
if (value) {
- convert_to_string_ex(value);
+ if (!try_convert_to_string(value)) {
+ return;
+ }
rl_pending_input = Z_STRVAL_P(value)[0];
}
RETVAL_LONG(oldval);
@@ -319,7 +323,9 @@ PHP_FUNCTION(readline_info)
} else if (!strcasecmp(what, "completion_append_character")) {
oldval = rl_completion_append_character;
if (value) {
- convert_to_string_ex(value)
+ if (!try_convert_to_string(value)) {
+ return;
+ }
rl_completion_append_character = (int)Z_STRVAL_P(value)[0];
}
RETVAL_INTERNED_STR(
@@ -342,7 +348,9 @@ PHP_FUNCTION(readline_info)
oldstr = (char*)rl_readline_name;
if (value) {
/* XXX if (rl_readline_name) free(rl_readline_name); */
- convert_to_string_ex(value);
+ if (!try_convert_to_string(value)) {
+ return;
+ }
rl_readline_name = strdup(Z_STRVAL_P(value));
}
RETVAL_STRING(SAFE_STRING(oldstr));
@@ -394,9 +402,10 @@ PHP_FUNCTION(readline_clear_history)
}
/* }}} */
+
+#ifdef HAVE_HISTORY_LIST
/* {{{ proto array readline_list_history(void)
Lists the history */
-#ifndef HAVE_LIBEDIT
PHP_FUNCTION(readline_list_history)
{
HIST_ENTRY **history;
@@ -405,19 +414,49 @@ PHP_FUNCTION(readline_list_history)
return;
}
+ array_init(return_value);
+
+#if defined(HAVE_LIBEDIT) && defined(PHP_WIN32) /* Winedit on Windows */
history = history_list();
- array_init(return_value);
+ if (history) {
+ int i, n = history_length();
+ for (i = 0; i < n; i++) {
+ add_next_index_string(return_value, history[i]->line);
+ }
+ }
+
+#elif defined(HAVE_LIBEDIT) /* libedit */
+ {
+ HISTORY_STATE *hs;
+ int i;
+
+ using_history();
+ hs = history_get_history_state();
+ if (hs && hs->length) {
+ history = history_list();
+ if (history) {
+ for (i = 0; i < hs->length; i++) {
+ add_next_index_string(return_value, history[i]->line);
+ }
+ }
+ }
+ }
+
+#else /* readline */
+ history = history_list();
if (history) {
int i;
for (i = 0; history[i]; i++) {
- add_next_index_string(return_value,history[i]->line);
+ add_next_index_string(return_value, history[i]->line);
}
}
-}
#endif
+}
/* }}} */
+#endif
+
/* {{{ proto bool readline_read_history([string filename])
Reads the history */
PHP_FUNCTION(readline_read_history)
@@ -513,7 +552,7 @@ static char **_readline_completion_cb(const char *text, int start, int end)
_readline_long_zval(&params[1], start);
_readline_long_zval(&params[2], end);
- if (call_user_function(CG(function_table), NULL, &_readline_completion, &_readline_array, 3, params) == SUCCESS) {
+ if (call_user_function(NULL, NULL, &_readline_completion, &_readline_array, 3, params) == SUCCESS) {
if (Z_TYPE(_readline_array) == IS_ARRAY) {
if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) {
matches = rl_completion_matches(text,_readline_command_generator);
@@ -572,7 +611,7 @@ static void php_rl_callback_handler(char *the_line)
_readline_string_zval(&params[0], the_line);
- call_user_function(CG(function_table), NULL, &_prepped_callback, &dummy, 1, params);
+ call_user_function(NULL, NULL, &_prepped_callback, &dummy, 1, params);
zval_ptr_dtor(&params[0]);
zval_ptr_dtor(&dummy);
@@ -614,6 +653,10 @@ PHP_FUNCTION(readline_callback_handler_install)
Informs the readline callback interface that a character is ready for input */
PHP_FUNCTION(readline_callback_read_char)
{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_read_char();
}
@@ -624,6 +667,10 @@ PHP_FUNCTION(readline_callback_read_char)
Removes a previously installed callback handler and restores terminal settings */
PHP_FUNCTION(readline_callback_handler_remove)
{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove();
zval_ptr_dtor(&_prepped_callback);
@@ -638,6 +685,10 @@ PHP_FUNCTION(readline_callback_handler_remove)
Ask readline to redraw the display */
PHP_FUNCTION(readline_redisplay)
{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
#if HAVE_LIBEDIT
/* seems libedit doesn't take care of rl_initialize in rl_redisplay
* see bug #72538 */
@@ -654,6 +705,10 @@ PHP_FUNCTION(readline_redisplay)
Inform readline that the cursor has moved to a new line */
PHP_FUNCTION(readline_on_new_line)
{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
rl_on_new_line();
}
/* }}} */
@@ -662,10 +717,3 @@ PHP_FUNCTION(readline_on_new_line)
#endif /* HAVE_LIBREADLINE */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- */
diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c
index 6e6e9161be..d7d96b59e1 100644
--- a/ext/readline/readline_cli.c
+++ b/ext/readline/readline_cli.c
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2018 The PHP Group |
+ | Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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 |
@@ -33,10 +33,7 @@
#include "zend_modules.h"
#include "SAPI.h"
-
-#if HAVE_SETLOCALE
#include <locale.h>
-#endif
#include "zend.h"
#include "zend_extensions.h"
#include "php_ini.h"
@@ -213,7 +210,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{
int brace_count = 0;
size_t i;
php_code_type code_type = body;
- char *heredoc_tag;
+ char *heredoc_tag = NULL;
size_t heredoc_len;
for (i = 0; i < len; ++i) {
@@ -285,6 +282,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{
if (i + 2 < len && code[i+1] == '<' && code[i+2] == '<') {
i += 2;
code_type = heredoc_start;
+ heredoc_tag = NULL;
heredoc_len = 0;
}
break;
@@ -336,10 +334,15 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{
break;
case '\r':
case '\n':
- code_type = heredoc;
+ if (heredoc_tag) {
+ code_type = heredoc;
+ } else {
+ /* Malformed heredoc without label */
+ code_type = body;
+ }
break;
default:
- if (!heredoc_len) {
+ if (!heredoc_tag) {
heredoc_tag = code+i;
}
heredoc_len++;
@@ -347,6 +350,7 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{
}
break;
case heredoc:
+ ZEND_ASSERT(heredoc_tag);
if (!strncmp(code + i - heredoc_len + 1, heredoc_tag, heredoc_len)) {
unsigned char c = code[i + 1];
char *p = code + i - heredoc_len;
@@ -520,13 +524,12 @@ TODO:
retval = cli_completion_generator_ini(text, textlen, &cli_completion_state);
} else {
char *lc_text, *class_name_end;
- size_t class_name_len;
- zend_string *class_name;
+ zend_string *class_name = NULL;
zend_class_entry *ce = NULL;
class_name_end = strstr(text, "::");
if (class_name_end) {
- class_name_len = class_name_end - text;
+ size_t class_name_len = class_name_end - text;
class_name = zend_string_alloc(class_name_len, 0);
zend_str_tolower_copy(ZSTR_VAL(class_name), text, class_name_len);
if ((ce = zend_lookup_class(class_name)) == NULL) {
@@ -560,11 +563,11 @@ TODO:
break;
}
efree(lc_text);
- if (class_name_end) {
+ if (class_name) {
zend_string_release_ex(class_name, 0);
}
if (ce && retval) {
- size_t len = class_name_len + 2 + strlen(retval) + 1;
+ size_t len = ZSTR_LEN(ce->name) + 2 + strlen(retval) + 1;
char *tmp = malloc(len);
snprintf(tmp, len, "%s::%s", ZSTR_VAL(ce->name), retval);
@@ -592,17 +595,9 @@ static int readline_shell_run(void) /* {{{ */
int history_lines_to_write = 0;
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
- zend_file_handle *prepend_file_p;
zend_file_handle prepend_file;
-
- memset(&prepend_file, 0, sizeof(prepend_file));
- prepend_file.filename = PG(auto_prepend_file);
- prepend_file.opened_path = NULL;
- prepend_file.free_filename = 0;
- prepend_file.type = ZEND_HANDLE_FILENAME;
- prepend_file_p = &prepend_file;
-
- zend_execute_scripts(ZEND_REQUIRE, NULL, 1, prepend_file_p);
+ zend_stream_init_filename(&prepend_file, PG(auto_prepend_file));
+ zend_execute_scripts(ZEND_REQUIRE, NULL, 1, &prepend_file);
}
#ifndef PHP_WIN32
@@ -798,12 +793,3 @@ PHP_MINFO_FUNCTION(cli_readline)
DISPLAY_INI_ENTRIES();
}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: sw=4 ts=4 fdm=marker
- * vim<600: sw=4 ts=4
- */
diff --git a/ext/readline/readline_cli.h b/ext/readline/readline_cli.h
index 0448a8f3c8..05c70c1dac 100644
--- a/ext/readline/readline_cli.h
+++ b/ext/readline/readline_cli.h
@@ -2,7 +2,7 @@
+----------------------------------------------------------------------+
| PHP Version 7 |
+----------------------------------------------------------------------+
- | Copyright (c) 1997-2018 The PHP Group |
+ | Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| 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 |
diff --git a/ext/readline/tests/readline_basic.phpt b/ext/readline/tests/readline_basic.phpt
new file mode 100644
index 0000000000..499601a436
--- /dev/null
+++ b/ext/readline/tests/readline_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+readline(): Basic test
+--CREDITS--
+Milwaukee PHP User Group
+#PHPTestFest2017
+--SKIPIF--
+<?php if (!extension_loaded("readline")) die("skip"); ?>
+--FILE--
+<?php
+
+var_dump(readline('Enter some text:'));
+
+?>
+--STDIN--
+I love PHP
+--EXPECTF--
+%Astring(10) "I love PHP"
diff --git a/ext/readline/tests/readline_read_history_001.phpt b/ext/readline/tests/readline_read_history_001.phpt
index fcdb1ae325..6cabaf369b 100644
--- a/ext/readline/tests/readline_read_history_001.phpt
+++ b/ext/readline/tests/readline_read_history_001.phpt
@@ -5,9 +5,9 @@ readline_read_history(): Basic test
--FILE--
<?php
-$name = tempnam('/tmp', 'readline.tmp');
+$name = tempnam(sys_get_temp_dir(), 'readline.tmp');
-readline_add_history("foo\n");
+readline_add_history("foo");
var_dump(readline_write_history($name));
diff --git a/ext/readline/tests/readline_read_history_error_001.phpt b/ext/readline/tests/readline_read_history_error_001.phpt
index 836c83b807..0d90280d8d 100644
--- a/ext/readline/tests/readline_read_history_error_001.phpt
+++ b/ext/readline/tests/readline_read_history_error_001.phpt
@@ -8,9 +8,7 @@ Pedro Manoel Evangelista <pedro.evangelista at gmail dot com>
<?php if (!READLINE_LIB != "libedit") die('skip READLINE_LIB != "libedit"'); ?>
--FILE--
<?php
-var_dump(readline_read_history());
var_dump(readline_read_history('nofile'));
?>
--EXPECT--
bool(false)
-bool(false)
diff --git a/ext/readline/tests/readline_without_input.phpt b/ext/readline/tests/readline_without_input.phpt
new file mode 100644
index 0000000000..e269c5eaa9
--- /dev/null
+++ b/ext/readline/tests/readline_without_input.phpt
@@ -0,0 +1,15 @@
+--TEST--
+readline() function - without input
+--CREDITS--
+Jonathan Stevens <info at jonathanstevens dot be>
+User Group: PHP-WVL & PHPGent #PHPTestFest
+--SKIPIF--
+<?php if (!extension_loaded("readline") || !function_exists('readline') || die("skip"); ?>
+--FILE--
+<?php
+var_dump(readline());
+var_dump(readline('Prompt:'));
+?>
+--EXPECTF--
+bool(false)
+%Abool(false)