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

Generated by: LCOV version 1.10

Generated at Wed, 04 May 2016 01:00:57 +0000 (25 hours ago)

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