root/ext/readline/readline.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ZEND_GET_MODULE
  2. PHP_MSHUTDOWN_FUNCTION
  3. PHP_RSHUTDOWN_FUNCTION
  4. PHP_MINFO_FUNCTION
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION
  10. PHP_FUNCTION
  11. PHP_FUNCTION
  12. _readline_command_generator
  13. _readline_string_zval
  14. _readline_long_zval
  15. _readline_completion_cb
  16. PHP_FUNCTION
  17. php_rl_callback_handler
  18. PHP_FUNCTION
  19. PHP_FUNCTION
  20. PHP_FUNCTION
  21. PHP_FUNCTION
  22. PHP_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */