]> granicus.if.org Git - php/commitdiff
phpng support for ext/readline
authorDmitry Stogov <dmitry@zend.com>
Sun, 18 May 2014 11:49:35 +0000 (15:49 +0400)
committerDmitry Stogov <dmitry@zend.com>
Sun, 18 May 2014 11:49:35 +0000 (15:49 +0400)
ext/readline/readline.c
ext/readline/readline_cli.c

index 3af1caabea21c95f3e5054306fadfca6b7a312dd..22b727b6a4f2dd90b0fcd45fd11dd368908037a6 100644 (file)
@@ -59,11 +59,11 @@ PHP_FUNCTION(readline_callback_handler_remove);
 PHP_FUNCTION(readline_redisplay);
 PHP_FUNCTION(readline_on_new_line);
 
-static zval *_prepped_callback = NULL;
+static zval _prepped_callback;
 
 #endif
 
-static zval *_readline_completion = NULL;
+static zval _readline_completion;
 static zval _readline_array;
 
 PHP_MINIT_FUNCTION(readline);
@@ -172,9 +172,13 @@ PHP_MINIT_FUNCTION(readline)
 {
 #if HAVE_LIBREADLINE
                /* libedit don't need this call which set the tty in cooked mode */
-               using_history();
+       using_history();
+#endif
+       ZVAL_UNDEF(&_readline_completion);
+#if HAVE_RL_CALLBACK_READ_CHAR
+       ZVAL_UNDEF(&_prepped_callback);
 #endif
-       return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
+       return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
 }
 
 PHP_MSHUTDOWN_FUNCTION(readline)
@@ -184,15 +188,13 @@ PHP_MSHUTDOWN_FUNCTION(readline)
 
 PHP_RSHUTDOWN_FUNCTION(readline)
 {
-       if (_readline_completion) {
-               zval_dtor(_readline_completion);
-               FREE_ZVAL(_readline_completion);
-       }
+       zval_dtor(&_readline_completion);
+       ZVAL_UNDEF(&_readline_completion);
 #if HAVE_RL_CALLBACK_READ_CHAR
-       if (_prepped_callback) {
+       if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
                rl_callback_handler_remove();
                zval_ptr_dtor(&_prepped_callback);
-               _prepped_callback = 0;
+               ZVAL_UNDEF(&_prepped_callback);
        }
 #endif
 
@@ -223,7 +225,7 @@ PHP_FUNCTION(readline)
        if (! result) {
                RETURN_FALSE;
        } else {
-               RETVAL_STRING(result,1);
+               RETVAL_STRING(result);
                free(result);
        }
 }
@@ -237,11 +239,11 @@ PHP_FUNCTION(readline)
 PHP_FUNCTION(readline_info)
 {
        char *what = NULL;
-       zval **value = NULL;
+       zval *value = NULL;
        int what_len, oldval;
        char *oldstr;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sZ", &what, &what_len, &value) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sz", &what, &what_len, &value) == FAILURE) {
                return;
        }
 
@@ -269,9 +271,9 @@ PHP_FUNCTION(readline_info)
                        if (value) {
                                /* XXX if (rl_line_buffer) free(rl_line_buffer); */
                                convert_to_string_ex(value);
-                               rl_line_buffer = strdup(Z_STRVAL_PP(value));
+                               rl_line_buffer = strdup(Z_STRVAL_P(value));
                        }
-                       RETVAL_STRING(SAFE_STRING(oldstr),1);
+                       RETVAL_STRING(SAFE_STRING(oldstr));
                } else if (!strcasecmp(what, "point")) {
                        RETVAL_LONG(rl_point);
                } else if (!strcasecmp(what, "end")) {
@@ -283,20 +285,20 @@ PHP_FUNCTION(readline_info)
                        oldval = rl_done;
                        if (value) {
                                convert_to_long_ex(value);
-                               rl_done = Z_LVAL_PP(value);
+                               rl_done = Z_LVAL_P(value);
                        }
                        RETVAL_LONG(oldval);
                } else if (!strcasecmp(what, "pending_input")) {
                        oldval = rl_pending_input;
                        if (value) {
                                convert_to_string_ex(value);
-                               rl_pending_input = Z_STRVAL_PP(value)[0];
+                               rl_pending_input = Z_STRVAL_P(value)[0];
                        }
                        RETVAL_LONG(oldval);
                } else if (!strcasecmp(what, "prompt")) {
-                       RETVAL_STRING(SAFE_STRING(rl_prompt),1);
+                       RETVAL_STRING(SAFE_STRING(rl_prompt));
                } else if (!strcasecmp(what, "terminal_name")) {
-                       RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name),1);
+                       RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name));
 #endif
 #if HAVE_ERASE_EMPTY_LINE
                } else if (!strcasecmp(what, "erase_empty_line")) {
@@ -308,20 +310,20 @@ PHP_FUNCTION(readline_info)
                        RETVAL_LONG(oldval);
 #endif
                } else if (!strcasecmp(what,"library_version")) {
-                       RETVAL_STRING((char *)SAFE_STRING(rl_library_version),1);
+                       RETVAL_STRING((char *)SAFE_STRING(rl_library_version));
                } else if (!strcasecmp(what, "readline_name")) {
                        oldstr = (char*)rl_readline_name;
                        if (value) {
                                /* XXX if (rl_readline_name) free(rl_readline_name); */
                                convert_to_string_ex(value);
-                               rl_readline_name = strdup(Z_STRVAL_PP(value));;
+                               rl_readline_name = strdup(Z_STRVAL_P(value));;
                        }
-                       RETVAL_STRING(SAFE_STRING(oldstr),1);
+                       RETVAL_STRING(SAFE_STRING(oldstr));
                } else if (!strcasecmp(what, "attempted_completion_over")) {
                        oldval = rl_attempted_completion_over;
                        if (value) {
                                convert_to_long_ex(value);
-                               rl_attempted_completion_over = Z_LVAL_PP(value);
+                               rl_attempted_completion_over = Z_LVAL_P(value);
                        }
                        RETVAL_LONG(oldval);
                }
@@ -442,63 +444,50 @@ PHP_FUNCTION(readline_write_history)
 static char *_readline_command_generator(const char *text, int state)
 {
        HashTable  *myht = Z_ARRVAL(_readline_array);
-       zval **entry;
+       zval *entry;
        
        if (!state) {
                zend_hash_internal_pointer_reset(myht);
        }
        
-       while (zend_hash_get_current_data(myht, (void **)&entry) == SUCCESS) {
+       while ((entry = zend_hash_get_current_data(myht)) != NULL) {
                zend_hash_move_forward(myht);
 
                convert_to_string_ex(entry);
-               if (strncmp (Z_STRVAL_PP(entry), text, strlen(text)) == 0) {
-                       return (strdup(Z_STRVAL_PP(entry)));
+               if (strncmp (Z_STRVAL_P(entry), text, strlen(text)) == 0) {
+                       return (strdup(Z_STRVAL_P(entry)));
                }
        }
 
        return NULL;
 }
 
-static zval *_readline_string_zval(const char *str)
+static void _readline_string_zval(zval *ret, const char *str)
 {
-       zval *ret;
-       int len;
-       
-       MAKE_STD_ZVAL(ret);
-       
        if (str) {
-               len = strlen(str);
-               ZVAL_STRINGL(ret, (char*)str, len, 1);
+               ZVAL_STRING(ret, (char*)str);
        } else {
                ZVAL_NULL(ret);
        }
-
-       return ret;
 }
 
-static zval *_readline_long_zval(long l)
+static void _readline_long_zval(zval *ret, long l)
 {
-       zval *ret;
-       MAKE_STD_ZVAL(ret);
-
-       Z_TYPE_P(ret) = IS_LONG;
-       Z_LVAL_P(ret) = l;
-       return ret;
+       ZVAL_LONG(ret, l);
 }
 
 static char **_readline_completion_cb(const char *text, int start, int end)
 { 
-       zval *params[3];
+       zval params[3];
        int i;
        char **matches = NULL;
        TSRMLS_FETCH();
 
-       params[0]=_readline_string_zval(text);
-       params[1]=_readline_long_zval(start);
-       params[2]=_readline_long_zval(end);
+       _readline_string_zval(&params[0], text);
+       _readline_long_zval(&params[1], start);
+       _readline_long_zval(&params[2], end);
 
-       if (call_user_function(CG(function_table), NULL, _readline_completion, &_readline_array, 3, params TSRMLS_CC) == SUCCESS) {
+       if (call_user_function(CG(function_table), NULL, &_readline_completion, &_readline_array, 3, params TSRMLS_CC) == SUCCESS) {
                if (Z_TYPE(_readline_array) == IS_ARRAY) {
                        if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) {
                                matches = rl_completion_matches(text,_readline_command_generator);
@@ -524,31 +513,24 @@ static char **_readline_completion_cb(const char *text, int start, int end)
 PHP_FUNCTION(readline_completion_function)
 {
        zval *arg = NULL;
-       char *name = NULL;
+       zend_string *name = NULL;
 
        if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg)) {
                RETURN_FALSE;
        }
 
        if (!zend_is_callable(arg, 0, &name TSRMLS_CC)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name);
-               efree(name);
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name->val);
+               STR_RELEASE(name);
                RETURN_FALSE;
        }
-       efree(name);
-
-       if (_readline_completion) {
-               zval_dtor(_readline_completion);
-               FREE_ZVAL(_readline_completion);
-       }
+       STR_RELEASE(name);
 
-       MAKE_STD_ZVAL(_readline_completion);
-       *_readline_completion = *arg;
-       zval_copy_ctor(_readline_completion);
+       zval_dtor(&_readline_completion);
+       ZVAL_DUP(&_readline_completion, arg);
 
        rl_attempted_completion_function = _readline_completion_cb;
        if (rl_attempted_completion_function == NULL) {
-               efree(name);
                RETURN_FALSE;
        }
        RETURN_TRUE;
@@ -560,15 +542,15 @@ PHP_FUNCTION(readline_completion_function)
 
 static void php_rl_callback_handler(char *the_line)
 {
-       zval *params[1];
+       zval params[1];
        zval dummy;
        TSRMLS_FETCH();
 
        ZVAL_NULL(&dummy);
 
-       params[0] = _readline_string_zval(the_line);
+       _readline_string_zval(&params[0], the_line);
 
-       call_user_function(CG(function_table), NULL, _prepped_callback, &dummy, 1, params TSRMLS_CC);
+       call_user_function(CG(function_table), NULL, &_prepped_callback, &dummy, 1, params TSRMLS_CC);
 
        zval_ptr_dtor(&params[0]);
        zval_dtor(&dummy);
@@ -579,7 +561,7 @@ static void php_rl_callback_handler(char *the_line)
 PHP_FUNCTION(readline_callback_handler_install)
 {
        zval *callback;
-       char *name = NULL;
+       zend_string *name = NULL;
        char *prompt;
        int prompt_len;
 
@@ -588,20 +570,18 @@ PHP_FUNCTION(readline_callback_handler_install)
        }
 
        if (!zend_is_callable(callback, 0, &name TSRMLS_CC)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name);
-               efree(name);
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name->val);
+               STR_RELEASE(name);
                RETURN_FALSE;
        }
-       efree(name);
+       STR_RELEASE(name);
 
-       if (_prepped_callback) {
+       if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
                rl_callback_handler_remove();
-               zval_dtor(_prepped_callback);
-               FREE_ZVAL(_prepped_callback);
+               zval_dtor(&_prepped_callback);
        }
 
-       ALLOC_ZVAL(_prepped_callback);
-       MAKE_COPY_ZVAL(&callback, _prepped_callback);
+       ZVAL_DUP(&_prepped_callback, callback);
 
        rl_callback_handler_install(prompt, php_rl_callback_handler);
 
@@ -613,7 +593,7 @@ PHP_FUNCTION(readline_callback_handler_install)
    Informs the readline callback interface that a character is ready for input */
 PHP_FUNCTION(readline_callback_read_char)
 {
-       if (_prepped_callback) {
+       if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
                rl_callback_read_char();
        }
 }
@@ -623,11 +603,10 @@ PHP_FUNCTION(readline_callback_read_char)
    Removes a previously installed callback handler and restores terminal settings */
 PHP_FUNCTION(readline_callback_handler_remove)
 {
-       if (_prepped_callback) {
+       if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
                rl_callback_handler_remove();
-               zval_dtor(_prepped_callback);
-               FREE_ZVAL(_prepped_callback);
-               _prepped_callback = 0;
+               zval_dtor(&_prepped_callback);
+               ZVAL_UNDEF(&_prepped_callback);
                RETURN_TRUE;
        }
        RETURN_FALSE;
index c2bf8764cb415939bcb7fba8629d74f9e439cd33..c94c2450716af25f5d3e9b5e828b00d27e9c12a9 100644 (file)
@@ -131,7 +131,7 @@ typedef enum {
        outside,
 } php_code_type;
 
-static char *cli_get_prompt(char *block, char prompt TSRMLS_DC) /* {{{ */
+static zend_string *cli_get_prompt(char *block, char prompt TSRMLS_DC) /* {{{ */
 {
        smart_str retval = {0};
        char *prompt_spec = CLIR_G(prompt) ? CLIR_G(prompt) : DEFAULT_PROMPT;
@@ -197,11 +197,11 @@ static char *cli_get_prompt(char *block, char prompt TSRMLS_DC) /* {{{ */
                }
        } while (++prompt_spec && *prompt_spec);
        smart_str_0(&retval);   
-       return retval.c;
+       return retval.s;
 }
 /* }}} */
 
-static int cli_is_valid_code(char *code, int len, char **prompt TSRMLS_DC) /* {{{ */
+static int cli_is_valid_code(char *code, int len, zend_string **prompt TSRMLS_DC) /* {{{ */
 {
        int valid_end = 1, last_valid_end;
        int brackets_count = 0;
@@ -405,7 +405,7 @@ static int cli_is_valid_code(char *code, int len, char **prompt TSRMLS_DC) /* {{
 
 static char *cli_completion_generator_ht(const char *text, int textlen, int *state, HashTable *ht, void **pData TSRMLS_DC) /* {{{ */
 {
-       char *name;
+       zend_string *name;
        ulong number;
 
        if (!(*state % 2)) {
@@ -414,12 +414,12 @@ static char *cli_completion_generator_ht(const char *text, int textlen, int *sta
        }
        while(zend_hash_has_more_elements(ht) == SUCCESS) {
                zend_hash_get_current_key(ht, &name, &number, 0);
-               if (!textlen || !strncmp(name, text, textlen)) {
+               if (!textlen || !strncmp(name->val, text, textlen)) {
                        if (pData) {
-                               zend_hash_get_current_data(ht, pData);
+                               *pData = zend_hash_get_current_data_ptr(ht);
                        }
                        zend_hash_move_forward(ht);
-                       return name;
+                       return name->val;
                }
                if (zend_hash_move_forward(ht) == FAILURE) {
                        break;
@@ -433,7 +433,7 @@ static char *cli_completion_generator_var(const char *text, int textlen, int *st
 {
        char *retval, *tmp;
 
-       tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, EG(active_symbol_table), NULL TSRMLS_CC);
+       tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, EG(active_symbol_table) ? &EG(active_symbol_table)->ht : NULL, NULL TSRMLS_CC);
        if (retval) {
                retval = malloc(strlen(tmp) + 2);
                retval[0] = '$';
@@ -463,7 +463,7 @@ static char *cli_completion_generator_func(const char *text, int textlen, int *s
        char *retval = cli_completion_generator_ht(text, textlen, state, ht, (void**)&func TSRMLS_CC);
        if (retval) {
                rl_completion_append_character = '(';
-               retval = strdup(func->common.function_name);
+               retval = strdup(func->common.function_name->val);
        }
        
        return retval;
@@ -471,11 +471,11 @@ static char *cli_completion_generator_func(const char *text, int textlen, int *s
 
 static char *cli_completion_generator_class(const char *text, int textlen, int *state TSRMLS_DC) /* {{{ */
 {
-       zend_class_entry **pce;
-       char *retval = cli_completion_generator_ht(text, textlen, state, EG(class_table), (void**)&pce TSRMLS_CC);
+       zend_class_entry *ce;
+       char *retval = cli_completion_generator_ht(text, textlen, state, EG(class_table), (void**)&ce TSRMLS_CC);
        if (retval) {
                rl_completion_append_character = '\0';
-               retval = strdup((*pce)->name);
+               retval = strdup(ce->name->val);
        }
        
        return retval;
@@ -518,17 +518,18 @@ TODO:
        } else if (text[0] == '#') {
                retval = cli_completion_generator_ini(text, textlen, &cli_completion_state TSRMLS_CC);
        } else {
-               char *lc_text, *class_name, *class_name_end;
+               char *lc_text, *class_name_end;
                int class_name_len;
-               zend_class_entry **pce = NULL;
+               zend_string *class_name;
+               zend_class_entry *ce = NULL;
                
                class_name_end = strstr(text, "::");
                if (class_name_end) {
                        class_name_len = class_name_end - text;
-                       class_name = zend_str_tolower_dup(text, class_name_len);
-                       class_name[class_name_len] = '\0'; /* not done automatically */
-                       if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
-                               efree(class_name);
+                       class_name = STR_ALLOC(class_name_len, 0);
+                       zend_str_tolower_copy(class_name->val, text, class_name_len);
+                       if ((ce = zend_lookup_class(class_name TSRMLS_CC)) == NULL) {
+                               STR_RELEASE(class_name);
                                return NULL;
                        }
                        lc_text = zend_str_tolower_dup(class_name_end + 2, textlen - 2 - class_name_len);
@@ -540,14 +541,14 @@ TODO:
                switch (cli_completion_state) {
                        case 0:
                        case 1:
-                               retval = cli_completion_generator_func(lc_text, textlen, &cli_completion_state, pce ? &(*pce)->function_table : EG(function_table) TSRMLS_CC);
+                               retval = cli_completion_generator_func(lc_text, textlen, &cli_completion_state, ce ? &ce->function_table : EG(function_table) TSRMLS_CC);
                                if (retval) {
                                        break;
                                }
                        case 2:
                        case 3:
-                               retval = cli_completion_generator_define(text, textlen, &cli_completion_state, pce ? &(*pce)->constants_table : EG(zend_constants) TSRMLS_CC);
-                               if (retval || pce) {
+                               retval = cli_completion_generator_define(text, textlen, &cli_completion_state, ce ? &ce->constants_table : EG(zend_constants) TSRMLS_CC);
+                               if (retval || ce) {
                                        break;
                                }
                        case 4:
@@ -559,13 +560,13 @@ TODO:
                }
                efree(lc_text);
                if (class_name_end) {
-                       efree(class_name);
+                       STR_RELEASE(class_name);
                }
-               if (pce && retval) {
+               if (ce && retval) {
                        int len = class_name_len + 2 + strlen(retval) + 1;
                        char *tmp = malloc(len);
                        
-                       snprintf(tmp, len, "%s::%s", (*pce)->name, retval);
+                       snprintf(tmp, len, "%s::%s", ce->name->val, retval);
                        free(retval);
                        retval = tmp;
                }
@@ -585,7 +586,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
        char *line;
        size_t size = 4096, pos = 0, len;
        char *code = emalloc(size);
-       char *prompt = cli_get_prompt("php", '>' TSRMLS_CC);
+       zend_string *prompt = cli_get_prompt("php", '>' TSRMLS_CC);
        char *history_file;
 
        if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
@@ -607,7 +608,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
        read_history(history_file);
 
        EG(exit_status) = 0;
-       while ((line = readline(prompt)) != NULL) {
+       while ((line = readline(prompt->val)) != NULL) {
                if (strcmp(line, "exit") == 0 || strcmp(line, "quit") == 0) {
                        free(line);
                        break;
@@ -623,17 +624,15 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
                if (line[0] == '#') {
                        char *param = strstr(&line[1], "=");
                        if (param) {
-                               char *cmd;
-                               uint cmd_len;
+                               zend_string *cmd;
                                param++;
-                               cmd_len = param - &line[1] - 1;
-                               cmd = estrndup(&line[1], cmd_len);
+                               cmd = STR_INIT(&line[1], param - &line[1] - 1, 0);
 
-                               zend_alter_ini_entry_ex(cmd, cmd_len + 1, param, strlen(param), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
-                               efree(cmd);
+                               zend_alter_ini_entry_ex(cmd, param, strlen(param), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
+                               STR_RELEASE(cmd);
                                add_history(line);
 
-                               efree(prompt);
+                               STR_RELEASE(prompt);
                                /* TODO: This might be wrong! */
                                prompt = cli_get_prompt("php", '>' TSRMLS_CC);
                                continue;
@@ -654,7 +653,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
                }
 
                free(line);
-               efree(prompt);
+               STR_RELEASE(prompt);
 
                if (!cli_is_valid_code(code, pos, &prompt TSRMLS_CC)) {
                        continue;
@@ -684,7 +683,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
        write_history(history_file);
        free(history_file);
        efree(code);
-       efree(prompt);
+       STR_RELEASE(prompt);
        return EG(exit_status);
 }
 /* }}} */