PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/readline - readline.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 129 211 61.1 %
Date: 2016-08-28 Functions: 13 21 61.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2016 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Author: Thies C. Arntzen <thies@thieso.net>                          |
      16             :    +----------------------------------------------------------------------+
      17             : */
      18             : 
      19             : /* $Id$ */
      20             : 
      21             : /* {{{ includes & prototypes */
      22             : 
      23             : #ifdef HAVE_CONFIG_H
      24             : #include "config.h"
      25             : #endif
      26             : 
      27             : #include "php.h"
      28             : #include "php_readline.h"
      29             : #include "readline_cli.h"
      30             : 
      31             : #if HAVE_LIBREADLINE || HAVE_LIBEDIT
      32             : 
      33             : #ifndef HAVE_RL_COMPLETION_MATCHES
      34             : #define rl_completion_matches completion_matches
      35             : #endif
      36             : 
      37             : #ifdef HAVE_LIBEDIT
      38             : #include <editline/readline.h>
      39             : #else
      40             : #include <readline/readline.h>
      41             : #include <readline/history.h>
      42             : #endif
      43             : 
      44             : PHP_FUNCTION(readline);
      45             : PHP_FUNCTION(readline_add_history);
      46             : PHP_FUNCTION(readline_info);
      47             : PHP_FUNCTION(readline_clear_history);
      48             : #ifndef HAVE_LIBEDIT
      49             : PHP_FUNCTION(readline_list_history);
      50             : #endif
      51             : PHP_FUNCTION(readline_read_history);
      52             : PHP_FUNCTION(readline_write_history);
      53             : PHP_FUNCTION(readline_completion_function);
      54             : 
      55             : #if HAVE_RL_CALLBACK_READ_CHAR
      56             : PHP_FUNCTION(readline_callback_handler_install);
      57             : PHP_FUNCTION(readline_callback_read_char);
      58             : PHP_FUNCTION(readline_callback_handler_remove);
      59             : PHP_FUNCTION(readline_redisplay);
      60             : PHP_FUNCTION(readline_on_new_line);
      61             : 
      62             : static zval _prepped_callback;
      63             : 
      64             : #endif
      65             : 
      66             : static zval _readline_completion;
      67             : static zval _readline_array;
      68             : 
      69             : PHP_MINIT_FUNCTION(readline);
      70             : PHP_MSHUTDOWN_FUNCTION(readline);
      71             : PHP_RSHUTDOWN_FUNCTION(readline);
      72             : PHP_MINFO_FUNCTION(readline);
      73             : 
      74             : /* }}} */
      75             : 
      76             : /* {{{ arginfo */
      77             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline, 0, 0, 0)
      78             :         ZEND_ARG_INFO(0, prompt)
      79             : ZEND_END_ARG_INFO()
      80             : 
      81             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_info, 0, 0, 0)
      82             :         ZEND_ARG_INFO(0, varname)
      83             :         ZEND_ARG_INFO(0, newvalue)
      84             : ZEND_END_ARG_INFO()
      85             : 
      86             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_add_history, 0, 0, 1)
      87             :         ZEND_ARG_INFO(0, prompt)
      88             : ZEND_END_ARG_INFO()
      89             : 
      90             : ZEND_BEGIN_ARG_INFO(arginfo_readline_clear_history, 0)
      91             : ZEND_END_ARG_INFO()
      92             : 
      93             : #ifndef HAVE_LIBEDIT
      94             : ZEND_BEGIN_ARG_INFO(arginfo_readline_list_history, 0)
      95             : ZEND_END_ARG_INFO()
      96             : #endif
      97             : 
      98             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_read_history, 0, 0, 0)
      99             :         ZEND_ARG_INFO(0, filename)
     100             : ZEND_END_ARG_INFO()
     101             : 
     102             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_write_history, 0, 0, 0)
     103             :         ZEND_ARG_INFO(0, filename)
     104             : ZEND_END_ARG_INFO()
     105             : 
     106             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_completion_function, 0, 0, 1)
     107             :         ZEND_ARG_INFO(0, funcname)
     108             : ZEND_END_ARG_INFO()
     109             : 
     110             : #if HAVE_RL_CALLBACK_READ_CHAR
     111             : ZEND_BEGIN_ARG_INFO_EX(arginfo_readline_callback_handler_install, 0, 0, 2)
     112             :         ZEND_ARG_INFO(0, prompt)
     113             :         ZEND_ARG_INFO(0, callback)
     114             : ZEND_END_ARG_INFO()
     115             : 
     116             : ZEND_BEGIN_ARG_INFO(arginfo_readline_callback_read_char, 0)
     117             : ZEND_END_ARG_INFO()
     118             : 
     119             : ZEND_BEGIN_ARG_INFO(arginfo_readline_callback_handler_remove, 0)
     120             : ZEND_END_ARG_INFO()
     121             : 
     122             : ZEND_BEGIN_ARG_INFO(arginfo_readline_redisplay, 0)
     123             : ZEND_END_ARG_INFO()
     124             : 
     125             : #if HAVE_RL_ON_NEW_LINE
     126             : ZEND_BEGIN_ARG_INFO(arginfo_readline_on_new_line, 0)
     127             : ZEND_END_ARG_INFO()
     128             : #endif
     129             : #endif
     130             : /* }}} */
     131             : 
     132             : /* {{{ module stuff */
     133             : static const zend_function_entry php_readline_functions[] = {
     134             :         PHP_FE(readline,                                arginfo_readline)
     135             :         PHP_FE(readline_info,               arginfo_readline_info)
     136             :         PHP_FE(readline_add_history,            arginfo_readline_add_history)
     137             :         PHP_FE(readline_clear_history,          arginfo_readline_clear_history)
     138             : #ifndef HAVE_LIBEDIT
     139             :         PHP_FE(readline_list_history,           arginfo_readline_list_history)
     140             : #endif
     141             :         PHP_FE(readline_read_history,           arginfo_readline_read_history)
     142             :         PHP_FE(readline_write_history,          arginfo_readline_write_history)
     143             :         PHP_FE(readline_completion_function,arginfo_readline_completion_function)
     144             : #if HAVE_RL_CALLBACK_READ_CHAR
     145             :         PHP_FE(readline_callback_handler_install, arginfo_readline_callback_handler_install)
     146             :         PHP_FE(readline_callback_read_char,                     arginfo_readline_callback_read_char)
     147             :         PHP_FE(readline_callback_handler_remove,        arginfo_readline_callback_handler_remove)
     148             :         PHP_FE(readline_redisplay, arginfo_readline_redisplay)
     149             : #endif
     150             : #if HAVE_RL_ON_NEW_LINE
     151             :         PHP_FE(readline_on_new_line, arginfo_readline_on_new_line)
     152             : #endif
     153             :         PHP_FE_END
     154             : };
     155             : 
     156             : zend_module_entry readline_module_entry = {
     157             :         STANDARD_MODULE_HEADER,
     158             :         "readline",
     159             :         php_readline_functions,
     160             :         PHP_MINIT(readline),
     161             :         PHP_MSHUTDOWN(readline),
     162             :         NULL,
     163             :         PHP_RSHUTDOWN(readline),
     164             :         PHP_MINFO(readline),
     165             :         PHP_READLINE_VERSION,
     166             :         STANDARD_MODULE_PROPERTIES
     167             : };
     168             : 
     169             : #ifdef COMPILE_DL_READLINE
     170             : ZEND_GET_MODULE(readline)
     171             : #endif
     172             : 
     173       23504 : PHP_MINIT_FUNCTION(readline)
     174             : {
     175             : #if HAVE_LIBREADLINE
     176             :                 /* libedit don't need this call which set the tty in cooked mode */
     177       23504 :         using_history();
     178             : #endif
     179       23504 :         ZVAL_UNDEF(&_readline_completion);
     180             : #if HAVE_RL_CALLBACK_READ_CHAR
     181       23504 :         ZVAL_UNDEF(&_prepped_callback);
     182             : #endif
     183       23504 :         return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
     184             : }
     185             : 
     186       23544 : PHP_MSHUTDOWN_FUNCTION(readline)
     187             : {
     188       23544 :         return PHP_MSHUTDOWN(cli_readline)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
     189             : }
     190             : 
     191       23500 : PHP_RSHUTDOWN_FUNCTION(readline)
     192             : {
     193       23500 :         zval_ptr_dtor(&_readline_completion);
     194       23500 :         ZVAL_UNDEF(&_readline_completion);
     195             : #if HAVE_RL_CALLBACK_READ_CHAR
     196       23500 :         if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
     197           1 :                 rl_callback_handler_remove();
     198           1 :                 zval_ptr_dtor(&_prepped_callback);
     199           1 :                 ZVAL_UNDEF(&_prepped_callback);
     200             :         }
     201             : #endif
     202             : 
     203       23500 :         return SUCCESS;
     204             : }
     205             : 
     206         150 : PHP_MINFO_FUNCTION(readline)
     207             : {
     208         150 :         PHP_MINFO(cli_readline)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
     209         150 : }
     210             : 
     211             : /* }}} */
     212             : 
     213             : /* {{{ proto string readline([string prompt])
     214             :    Reads a line */
     215           0 : PHP_FUNCTION(readline)
     216             : {
     217           0 :         char *prompt = NULL;
     218             :         size_t prompt_len;
     219             :         char *result;
     220             : 
     221           0 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &prompt, &prompt_len)) {
     222           0 :                 RETURN_FALSE;
     223             :         }
     224             : 
     225           0 :         result = readline(prompt);
     226             : 
     227           0 :         if (! result) {
     228           0 :                 RETURN_FALSE;
     229             :         } else {
     230           0 :                 RETVAL_STRING(result);
     231           0 :                 free(result);
     232             :         }
     233             : }
     234             : 
     235             : /* }}} */
     236             : 
     237             : #define SAFE_STRING(s) ((s)?(char*)(s):"")
     238             : 
     239             : /* {{{ proto mixed readline_info([string varname [, string newvalue]])
     240             :    Gets/sets various internal readline variables. */
     241          12 : PHP_FUNCTION(readline_info)
     242             : {
     243          12 :         char *what = NULL;
     244          12 :         zval *value = NULL;
     245             :         size_t what_len, oldval;
     246             :         char *oldstr;
     247             : 
     248          12 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sz", &what, &what_len, &value) == FAILURE) {
     249           0 :                 return;
     250             :         }
     251             : 
     252          12 :         if (!what) {
     253           1 :                 array_init(return_value);
     254           1 :                 add_assoc_string(return_value,"line_buffer",SAFE_STRING(rl_line_buffer));
     255           1 :                 add_assoc_long(return_value,"point",rl_point);
     256             : #ifndef PHP_WIN32
     257           1 :                 add_assoc_long(return_value,"end",rl_end);
     258             : #endif
     259             : #ifdef HAVE_LIBREADLINE
     260           1 :                 add_assoc_long(return_value,"mark",rl_mark);
     261           1 :                 add_assoc_long(return_value,"done",rl_done);
     262           1 :                 add_assoc_long(return_value,"pending_input",rl_pending_input);
     263           1 :                 add_assoc_string(return_value,"prompt",SAFE_STRING(rl_prompt));
     264           1 :                 add_assoc_string(return_value,"terminal_name",(char *)SAFE_STRING(rl_terminal_name));
     265             : #endif
     266             : #if HAVE_ERASE_EMPTY_LINE
     267             :                 add_assoc_long(return_value,"erase_empty_line",rl_erase_empty_line);
     268             : #endif
     269             : #ifndef PHP_WIN32
     270           1 :                 add_assoc_string(return_value,"library_version",(char *)SAFE_STRING(rl_library_version));
     271             : #endif
     272           1 :                 add_assoc_string(return_value,"readline_name",(char *)SAFE_STRING(rl_readline_name));
     273           1 :                 add_assoc_long(return_value,"attempted_completion_over",rl_attempted_completion_over);
     274             :         } else {
     275          11 :                 if (!strcasecmp(what,"line_buffer")) {
     276           1 :                         oldstr = rl_line_buffer;
     277           1 :                         if (value) {
     278             :                                 /* XXX if (rl_line_buffer) free(rl_line_buffer); */
     279           0 :                                 convert_to_string_ex(value);
     280           0 :                                 rl_line_buffer = strdup(Z_STRVAL_P(value));
     281             :                         }
     282           2 :                         RETVAL_STRING(SAFE_STRING(oldstr));
     283          10 :                 } else if (!strcasecmp(what, "point")) {
     284           0 :                         RETVAL_LONG(rl_point);
     285             : #ifndef PHP_WIN32
     286          10 :                 } else if (!strcasecmp(what, "end")) {
     287           0 :                         RETVAL_LONG(rl_end);
     288             : #endif
     289             : #ifdef HAVE_LIBREADLINE
     290          10 :                 } else if (!strcasecmp(what, "mark")) {
     291           0 :                         RETVAL_LONG(rl_mark);
     292          10 :                 } else if (!strcasecmp(what, "done")) {
     293           3 :                         oldval = rl_done;
     294           3 :                         if (value) {
     295           0 :                                 convert_to_long_ex(value);
     296           0 :                                 rl_done = Z_LVAL_P(value);
     297             :                         }
     298           3 :                         RETVAL_LONG(oldval);
     299           7 :                 } else if (!strcasecmp(what, "pending_input")) {
     300           0 :                         oldval = rl_pending_input;
     301           0 :                         if (value) {
     302           0 :                                 convert_to_string_ex(value);
     303           0 :                                 rl_pending_input = Z_STRVAL_P(value)[0];
     304             :                         }
     305           0 :                         RETVAL_LONG(oldval);
     306           7 :                 } else if (!strcasecmp(what, "prompt")) {
     307           0 :                         RETVAL_STRING(SAFE_STRING(rl_prompt));
     308           7 :                 } else if (!strcasecmp(what, "terminal_name")) {
     309           0 :                         RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name));
     310             : #endif
     311             : #if HAVE_ERASE_EMPTY_LINE
     312             :                 } else if (!strcasecmp(what, "erase_empty_line")) {
     313             :                         oldval = rl_erase_empty_line;
     314             :                         if (value) {
     315             :                                 convert_to_long_ex(value);
     316             :                                 rl_erase_empty_line = Z_LVAL_P(value);
     317             :                         }
     318             :                         RETVAL_LONG(oldval);
     319             : #endif
     320             : #ifndef PHP_WIN32
     321           7 :                 } else if (!strcasecmp(what,"library_version")) {
     322           0 :                         RETVAL_STRING((char *)SAFE_STRING(rl_library_version));
     323             : #endif
     324           7 :                 } else if (!strcasecmp(what, "readline_name")) {
     325           3 :                         oldstr = (char*)rl_readline_name;
     326           3 :                         if (value) {
     327             :                                 /* XXX if (rl_readline_name) free(rl_readline_name); */
     328           3 :                                 convert_to_string_ex(value);
     329           1 :                                 rl_readline_name = strdup(Z_STRVAL_P(value));;
     330             :                         }
     331           6 :                         RETVAL_STRING(SAFE_STRING(oldstr));
     332           4 :                 } else if (!strcasecmp(what, "attempted_completion_over")) {
     333           2 :                         oldval = rl_attempted_completion_over;
     334           2 :                         if (value) {
     335           2 :                                 convert_to_long_ex(value);
     336           1 :                                 rl_attempted_completion_over = Z_LVAL_P(value);
     337             :                         }
     338           2 :                         RETVAL_LONG(oldval);
     339             :                 }
     340             :         }
     341             : }
     342             : 
     343             : /* }}} */
     344             : /* {{{ proto bool readline_add_history(string prompt)
     345             :    Adds a line to the history */
     346           8 : PHP_FUNCTION(readline_add_history)
     347             : {
     348             :         char *arg;
     349             :         size_t arg_len;
     350             : 
     351           8 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
     352           1 :                 return;
     353             :         }
     354             : 
     355           7 :         add_history(arg);
     356             : 
     357           7 :         RETURN_TRUE;
     358             : }
     359             : 
     360             : /* }}} */
     361             : /* {{{ proto bool readline_clear_history(void)
     362             :    Clears the history */
     363           4 : PHP_FUNCTION(readline_clear_history)
     364             : {
     365           4 :         if (zend_parse_parameters_none() == FAILURE) {
     366           1 :                 return;
     367             :         }
     368             : 
     369             : #if HAVE_LIBEDIT
     370             :         /* clear_history is the only function where rl_initialize
     371             :            is not call to ensure correct allocation */
     372             :         using_history();
     373             : #endif
     374           3 :         clear_history();
     375             : 
     376           3 :         RETURN_TRUE;
     377             : }
     378             : 
     379             : /* }}} */
     380             : /* {{{ proto array readline_list_history(void)
     381             :    Lists the history */
     382             : #ifndef HAVE_LIBEDIT
     383           5 : PHP_FUNCTION(readline_list_history)
     384             : {
     385             :         HIST_ENTRY **history;
     386             : 
     387           5 :         if (zend_parse_parameters_none() == FAILURE) {
     388           1 :                 return;
     389             :         }
     390             : 
     391           4 :         history = history_list();
     392             : 
     393           4 :         array_init(return_value);
     394             : 
     395           4 :         if (history) {
     396             :                 int i;
     397           7 :                 for (i = 0; history[i]; i++) {
     398           4 :                         add_next_index_string(return_value,history[i]->line);
     399             :                 }
     400             :         }
     401             : }
     402             : #endif
     403             : /* }}} */
     404             : /* {{{ proto bool readline_read_history([string filename])
     405             :    Reads the history */
     406           2 : PHP_FUNCTION(readline_read_history)
     407             : {
     408           2 :         char *arg = NULL;
     409             :         size_t arg_len;
     410             : 
     411           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p", &arg, &arg_len) == FAILURE) {
     412           0 :                 return;
     413             :         }
     414             : 
     415           2 :         if (arg && php_check_open_basedir(arg)) {
     416           0 :                 RETURN_FALSE;
     417             :         }
     418             : 
     419             :         /* XXX from & to NYI */
     420           2 :         if (read_history(arg)) {
     421             :                 /* If filename is NULL, then read from `~/.history' */
     422           1 :                 RETURN_FALSE;
     423             :         } else {
     424           1 :                 RETURN_TRUE;
     425             :         }
     426             : }
     427             : 
     428             : /* }}} */
     429             : /* {{{ proto bool readline_write_history([string filename])
     430             :    Writes the history */
     431           2 : PHP_FUNCTION(readline_write_history)
     432             : {
     433           2 :         char *arg = NULL;
     434             :         size_t arg_len;
     435             : 
     436           2 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p", &arg, &arg_len) == FAILURE) {
     437           0 :                 return;
     438             :         }
     439             : 
     440           2 :         if (arg && php_check_open_basedir(arg)) {
     441           0 :                 RETURN_FALSE;
     442             :         }
     443             : 
     444           2 :         if (write_history(arg)) {
     445           0 :                 RETURN_FALSE;
     446             :         } else {
     447           2 :                 RETURN_TRUE;
     448             :         }
     449             : }
     450             : 
     451             : /* }}} */
     452             : /* {{{ proto bool readline_completion_function(string funcname)
     453             :    Readline completion function? */
     454             : 
     455           0 : static char *_readline_command_generator(const char *text, int state)
     456             : {
     457           0 :         HashTable  *myht = Z_ARRVAL(_readline_array);
     458             :         zval *entry;
     459             : 
     460           0 :         if (!state) {
     461           0 :                 zend_hash_internal_pointer_reset(myht);
     462             :         }
     463             : 
     464           0 :         while ((entry = zend_hash_get_current_data(myht)) != NULL) {
     465           0 :                 zend_hash_move_forward(myht);
     466             : 
     467           0 :                 convert_to_string_ex(entry);
     468           0 :                 if (strncmp (Z_STRVAL_P(entry), text, strlen(text)) == 0) {
     469           0 :                         return (strdup(Z_STRVAL_P(entry)));
     470             :                 }
     471             :         }
     472             : 
     473           0 :         return NULL;
     474             : }
     475             : 
     476           0 : static void _readline_string_zval(zval *ret, const char *str)
     477             : {
     478           0 :         if (str) {
     479           0 :                 ZVAL_STRING(ret, (char*)str);
     480             :         } else {
     481           0 :                 ZVAL_NULL(ret);
     482             :         }
     483           0 : }
     484             : 
     485           0 : static void _readline_long_zval(zval *ret, long l)
     486             : {
     487           0 :         ZVAL_LONG(ret, l);
     488           0 : }
     489             : 
     490           0 : static char **_readline_completion_cb(const char *text, int start, int end)
     491             : {
     492             :         zval params[3];
     493             :         int i;
     494           0 :         char **matches = NULL;
     495             : 
     496           0 :         _readline_string_zval(&params[0], text);
     497           0 :         _readline_long_zval(&params[1], start);
     498           0 :         _readline_long_zval(&params[2], end);
     499             : 
     500           0 :         if (call_user_function(CG(function_table), NULL, &_readline_completion, &_readline_array, 3, params) == SUCCESS) {
     501           0 :                 if (Z_TYPE(_readline_array) == IS_ARRAY) {
     502           0 :                         if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) {
     503           0 :                                 matches = rl_completion_matches(text,_readline_command_generator);
     504             :                         } else {
     505           0 :                                 matches = malloc(sizeof(char *) * 2);
     506           0 :                                 if (!matches) {
     507           0 :                                         return NULL;
     508             :                                 }
     509           0 :                                 matches[0] = strdup("");
     510           0 :                                 matches[1] = '\0';
     511             :                         }
     512             :                 }
     513             :         }
     514             : 
     515           0 :         for (i = 0; i < 3; i++) {
     516           0 :                 zval_ptr_dtor(&params[i]);
     517             :         }
     518           0 :         zval_ptr_dtor(&_readline_array);
     519             : 
     520           0 :         return matches;
     521             : }
     522             : 
     523           4 : PHP_FUNCTION(readline_completion_function)
     524             : {
     525           4 :         zval *arg = NULL;
     526           4 :         zend_string *name = NULL;
     527             : 
     528           4 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg)) {
     529           0 :                 RETURN_FALSE;
     530             :         }
     531             : 
     532           4 :         if (!zend_is_callable(arg, 0, &name)) {
     533           2 :                 php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
     534           2 :                 zend_string_release(name);
     535           2 :                 RETURN_FALSE;
     536             :         }
     537           2 :         zend_string_release(name);
     538             : 
     539           2 :         zval_ptr_dtor(&_readline_completion);
     540           2 :         ZVAL_COPY(&_readline_completion, arg);
     541             : 
     542           2 :         rl_attempted_completion_function = _readline_completion_cb;
     543           2 :         if (rl_attempted_completion_function == NULL) {
     544           0 :                 RETURN_FALSE;
     545             :         }
     546           2 :         RETURN_TRUE;
     547             : }
     548             : 
     549             : /* }}} */
     550             : 
     551             : #if HAVE_RL_CALLBACK_READ_CHAR
     552             : 
     553           0 : static void php_rl_callback_handler(char *the_line)
     554             : {
     555             :         zval params[1];
     556             :         zval dummy;
     557             : 
     558           0 :         ZVAL_NULL(&dummy);
     559             : 
     560           0 :         _readline_string_zval(&params[0], the_line);
     561             : 
     562           0 :         call_user_function(CG(function_table), NULL, &_prepped_callback, &dummy, 1, params);
     563             : 
     564           0 :         zval_ptr_dtor(&params[0]);
     565           0 :         zval_ptr_dtor(&dummy);
     566           0 : }
     567             : 
     568             : /* {{{ proto void readline_callback_handler_install(string prompt, mixed callback)
     569             :    Initializes the readline callback interface and terminal, prints the prompt and returns immediately */
     570           5 : PHP_FUNCTION(readline_callback_handler_install)
     571             : {
     572             :         zval *callback;
     573           5 :         zend_string *name = NULL;
     574             :         char *prompt;
     575             :         size_t prompt_len;
     576             : 
     577           5 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &prompt, &prompt_len, &callback)) {
     578           1 :                 return;
     579             :         }
     580             : 
     581           4 :         if (!zend_is_callable(callback, 0, &name)) {
     582           1 :                 php_error_docref(NULL, E_WARNING, "%s is not callable", ZSTR_VAL(name));
     583           1 :                 zend_string_release(name);
     584           1 :                 RETURN_FALSE;
     585             :         }
     586           3 :         zend_string_release(name);
     587             : 
     588           3 :         if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
     589           1 :                 rl_callback_handler_remove();
     590           1 :                 zval_ptr_dtor(&_prepped_callback);
     591             :         }
     592             : 
     593           3 :         ZVAL_COPY(&_prepped_callback, callback);
     594             : 
     595           3 :         rl_callback_handler_install(prompt, php_rl_callback_handler);
     596             : 
     597           3 :         RETURN_TRUE;
     598             : }
     599             : /* }}} */
     600             : 
     601             : /* {{{ proto void readline_callback_read_char()
     602             :    Informs the readline callback interface that a character is ready for input */
     603           0 : PHP_FUNCTION(readline_callback_read_char)
     604             : {
     605           0 :         if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
     606           0 :                 rl_callback_read_char();
     607             :         }
     608           0 : }
     609             : /* }}} */
     610             : 
     611             : /* {{{ proto bool readline_callback_handler_remove()
     612             :    Removes a previously installed callback handler and restores terminal settings */
     613           2 : PHP_FUNCTION(readline_callback_handler_remove)
     614             : {
     615           2 :         if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
     616           1 :                 rl_callback_handler_remove();
     617           1 :                 zval_ptr_dtor(&_prepped_callback);
     618           1 :                 ZVAL_UNDEF(&_prepped_callback);
     619           1 :                 RETURN_TRUE;
     620             :         }
     621           1 :         RETURN_FALSE;
     622             : }
     623             : /* }}} */
     624             : 
     625             : /* {{{ proto void readline_redisplay(void)
     626             :    Ask readline to redraw the display */
     627           0 : PHP_FUNCTION(readline_redisplay)
     628             : {
     629             : #if HAVE_LIBEDIT
     630             :         /* seems libedit doesn't take care of rl_initialize in rl_redisplay
     631             :          * see bug #72538 */
     632             :         using_history();
     633             : #endif
     634           0 :         rl_redisplay();
     635           0 : }
     636             : /* }}} */
     637             : 
     638             : #endif
     639             : 
     640             : #if HAVE_RL_ON_NEW_LINE
     641             : /* {{{ proto void readline_on_new_line(void)
     642             :    Inform readline that the cursor has moved to a new line */
     643             : PHP_FUNCTION(readline_on_new_line)
     644             : {
     645             :         rl_on_new_line();
     646             : }
     647             : /* }}} */
     648             : 
     649             : #endif
     650             : 
     651             : 
     652             : #endif /* HAVE_LIBREADLINE */
     653             : 
     654             : /*
     655             :  * Local variables:
     656             :  * tab-width: 4
     657             :  * c-basic-offset: 4
     658             :  * End:
     659             :  */

Generated by: LCOV version 1.10

Generated at Sun, 28 Aug 2016 17:10:09 +0000 (28 hours ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.