readline.c 16 KB

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