Annotation of embedaddon/php/ext/readline/readline.c, revision 1.1.1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>