Merge branch 'phpng' of git.php.net:/php-src into phpng

Conflicts:
	ext/pdo/pdo_sql_parser.c
This commit is contained in:
Xinchen Hui 2014-05-18 21:06:44 +08:00
commit 583bb6339b
5 changed files with 170 additions and 199 deletions

View file

@ -1091,7 +1091,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
if (EG(scope) && if (EG(scope) &&
is_derived_class(fbc->common.scope, EG(scope)) && is_derived_class(fbc->common.scope, EG(scope)) &&
fbc->op_array.fn_flags & ZEND_ACC_CHANGED) { fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
if ((func = zend_hash_find(&EG(scope)->function_table, lc_method_name)) == NULL) { if ((func = zend_hash_find(&EG(scope)->function_table, lc_method_name)) != NULL) {
zend_function *priv_fbc = Z_FUNC_P(func); zend_function *priv_fbc = Z_FUNC_P(func);
if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
&& priv_fbc->common.scope == EG(scope)) { && priv_fbc->common.scope == EG(scope)) {

View file

@ -40,16 +40,14 @@ typedef struct _broker_struct {
EnchantBroker *pbroker; EnchantBroker *pbroker;
enchant_dict **dict; enchant_dict **dict;
unsigned int dictcnt; unsigned int dictcnt;
long rsrc_id; zend_resource *rsrc;
} _enchant_broker; } _enchant_broker;
typedef struct _dict_struct { typedef struct _dict_struct {
unsigned int id; unsigned int id;
EnchantDict *pdict; EnchantDict *pdict;
enchant_broker *pbroker; enchant_broker *pbroker;
long rsrc_id; zend_resource *rsrc;
enchant_dict *next;
enchant_dict *prev;
} _enchant_dict; } _enchant_dict;
@ -181,20 +179,19 @@ enumerate_providers_fn (const char * const name,
void * ud) /* {{{ */ void * ud) /* {{{ */
{ {
zval *zdesc = (zval *) ud; zval *zdesc = (zval *) ud;
zval *tmp_array; zval tmp_array;
MAKE_STD_ZVAL(tmp_array); array_init(&tmp_array);
array_init(tmp_array);
add_assoc_string(tmp_array, "name", (char *)name); add_assoc_string(&tmp_array, "name", (char *)name);
add_assoc_string(tmp_array, "desc", (char *)desc); add_assoc_string(&tmp_array, "desc", (char *)desc);
add_assoc_string(tmp_array, "file", (char *)file); add_assoc_string(&tmp_array, "file", (char *)file);
if (Z_TYPE_P(zdesc)!=IS_ARRAY) { if (Z_TYPE_P(zdesc)!=IS_ARRAY) {
array_init(zdesc); array_init(zdesc);
} }
add_next_index_zval(zdesc, tmp_array); add_next_index_zval(zdesc, &tmp_array);
} }
/* }}} */ /* }}} */
@ -219,24 +216,23 @@ static void php_enchant_list_dicts_fn( const char * const lang_tag,
const char * const provider_file, void * ud) /* {{{ */ const char * const provider_file, void * ud) /* {{{ */
{ {
zval *zdesc = (zval *) ud; zval *zdesc = (zval *) ud;
zval *tmp_array; zval tmp_array;
MAKE_STD_ZVAL(tmp_array); array_init(&tmp_array);
array_init(tmp_array); add_assoc_string(&tmp_array, "lang_tag", (char *)lang_tag);
add_assoc_string(tmp_array, "lang_tag", (char *)lang_tag); add_assoc_string(&tmp_array, "provider_name", (char *)provider_name);
add_assoc_string(tmp_array, "provider_name", (char *)provider_name); add_assoc_string(&tmp_array, "provider_desc", (char *)provider_desc);
add_assoc_string(tmp_array, "provider_desc", (char *)provider_desc); add_assoc_string(&tmp_array, "provider_file", (char *)provider_file);
add_assoc_string(tmp_array, "provider_file", (char *)provider_file);
if (Z_TYPE_P(zdesc) != IS_ARRAY) { if (Z_TYPE_P(zdesc) != IS_ARRAY) {
array_init(zdesc); array_init(zdesc);
} }
add_next_index_zval(zdesc, tmp_array); add_next_index_zval(zdesc, &tmp_array);
} }
/* }}} */ /* }}} */
static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ static void php_enchant_broker_free(zend_resource *rsrc TSRMLS_DC) /* {{{ */
{ {
if (rsrc->ptr) { if (rsrc->ptr) {
enchant_broker *broker = (enchant_broker *)rsrc->ptr; enchant_broker *broker = (enchant_broker *)rsrc->ptr;
@ -247,8 +243,12 @@ static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{
int total; int total;
total = broker->dictcnt-1; total = broker->dictcnt-1;
do { do {
zend_list_delete(broker->dict[total]->rsrc_id); if (broker->dict[total]) {
efree(broker->dict[total]); enchant_dict *pdict = broker->dict[total];
broker->dict[total] = NULL;
zend_list_free(pdict->rsrc);
efree(pdict);
}
total--; total--;
} while (total>=0); } while (total>=0);
} }
@ -263,20 +263,21 @@ static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{
} }
/* }}} */ /* }}} */
static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ static void php_enchant_dict_free(zend_resource *rsrc TSRMLS_DC) /* {{{ */
{ {
if (rsrc->ptr) { if (rsrc->ptr) {
enchant_dict *pdict = (enchant_dict *)rsrc->ptr; enchant_dict *pdict = (enchant_dict *)rsrc->ptr;
if (pdict) { if (pdict) {
if (pdict->pdict && pdict->pbroker) { enchant_broker *pbroker = pdict->pbroker;
enchant_broker_free_dict(pdict->pbroker->pbroker, pdict->pdict);
if (pdict->id) { if (pdict->pdict && pbroker) {
pdict->pbroker->dict[pdict->id-1]->next = NULL; enchant_broker_free_dict(pbroker->pbroker, pdict->pdict);
}
zend_list_delete(pdict->pbroker->rsrc_id);
} }
pbroker->dict[pdict->id] = NULL;
efree(pdict);
zend_list_delete(pbroker->rsrc);
} }
} }
} }
@ -337,14 +338,14 @@ PHP_MINFO_FUNCTION(enchant)
/* }}} */ /* }}} */
#define PHP_ENCHANT_GET_BROKER \ #define PHP_ENCHANT_GET_BROKER \
ZEND_FETCH_RESOURCE(pbroker, enchant_broker *, &broker, -1, "enchant_broker", le_enchant_broker); \ ZEND_FETCH_RESOURCE(pbroker, enchant_broker *, broker, -1, "enchant_broker", le_enchant_broker); \
if (!pbroker || !pbroker->pbroker) { \ if (!pbroker || !pbroker->pbroker) { \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Resource broker invalid"); \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Resource broker invalid"); \
RETURN_FALSE; \ RETURN_FALSE; \
} }
#define PHP_ENCHANT_GET_DICT \ #define PHP_ENCHANT_GET_DICT \
ZEND_FETCH_RESOURCE(pdict, enchant_dict *, &dict, -1, "enchant_dict", le_enchant_dict); \ ZEND_FETCH_RESOURCE(pdict, enchant_dict *, dict, -1, "enchant_dict", le_enchant_dict); \
if (!pdict || !pdict->pdict) { \ if (!pdict || !pdict->pdict) { \
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Invalid dictionary resource."); \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", "Invalid dictionary resource."); \
RETURN_FALSE; \ RETURN_FALSE; \
@ -368,7 +369,7 @@ PHP_FUNCTION(enchant_broker_init)
broker->pbroker = pbroker; broker->pbroker = pbroker;
broker->dict = NULL; broker->dict = NULL;
broker->dictcnt = 0; broker->dictcnt = 0;
broker->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, broker, le_enchant_broker); broker->rsrc = ZEND_REGISTER_RESOURCE(return_value, broker, le_enchant_broker);
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -387,7 +388,7 @@ PHP_FUNCTION(enchant_broker_free)
} }
PHP_ENCHANT_GET_BROKER; PHP_ENCHANT_GET_BROKER;
zend_list_delete(Z_RESVAL_P(broker)); zend_list_close(Z_RES_P(broker));
RETURN_TRUE; RETURN_TRUE;
} }
/* }}} */ /* }}} */
@ -408,7 +409,7 @@ PHP_FUNCTION(enchant_broker_get_error)
msg = enchant_broker_get_error(pbroker->pbroker); msg = enchant_broker_get_error(pbroker->pbroker);
if (msg) { if (msg) {
RETURN_STRING((char *)msg, 1); RETURN_STRING((char *)msg);
} }
RETURN_FALSE; RETURN_FALSE;
} }
@ -563,16 +564,10 @@ PHP_FUNCTION(enchant_broker_request_dict)
dict->id = pos; dict->id = pos;
dict->pbroker = pbroker; dict->pbroker = pbroker;
dict->pdict = d; dict->pdict = d;
dict->prev = pos ? pbroker->dict[pos-1] : NULL;
dict->next = NULL;
pbroker->dict[pos] = dict; pbroker->dict[pos] = dict;
if (pos) { dict->rsrc = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
pbroker->dict[pos-1]->next = dict; pbroker->rsrc->gc.refcount++;
}
dict->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
zend_list_addref(pbroker->rsrc_id);
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -619,13 +614,10 @@ PHP_FUNCTION(enchant_broker_request_pwl_dict)
dict->id = pos; dict->id = pos;
dict->pbroker = pbroker; dict->pbroker = pbroker;
dict->pdict = d; dict->pdict = d;
dict->prev = pos?pbroker->dict[pos-1]:NULL;
dict->next = NULL;
pbroker->dict[pos] = dict; pbroker->dict[pos] = dict;
if (pos) {
pbroker->dict[pos-1]->next = dict; dict->rsrc = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
} pbroker->rsrc->gc.refcount++;
dict->rsrc_id = ZEND_REGISTER_RESOURCE(return_value, dict, le_enchant_dict);
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -645,7 +637,7 @@ PHP_FUNCTION(enchant_broker_free_dict)
PHP_ENCHANT_GET_DICT; PHP_ENCHANT_GET_DICT;
zend_list_delete(Z_RESVAL_P(dict)); zend_list_close(Z_RES_P(dict));
RETURN_TRUE; RETURN_TRUE;
} }
/* }}} */ /* }}} */
@ -909,7 +901,7 @@ PHP_FUNCTION(enchant_dict_get_error)
msg = enchant_dict_get_error(pdict->pdict); msg = enchant_dict_get_error(pdict->pdict);
if (msg) { if (msg) {
RETURN_STRING((char *)msg, 1); RETURN_STRING((char *)msg);
} }
RETURN_FALSE; RETURN_FALSE;

View file

@ -41,16 +41,17 @@
#define TRACE_APPEND_STR(val) \ #define TRACE_APPEND_STR(val) \
TRACE_APPEND_STRL(val, sizeof(val)-1) TRACE_APPEND_STRL(val, sizeof(val)-1)
#define TRACE_APPEND_KEY(key) \ inline void trace_append_key(HashTable *ht, const char *key) {
if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ zval *ztmp;
TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ if ((ztmp = zend_hash_str_find(ht, key, sizeof(key))) != NULL) {
} TRACE_APPEND_STRL(Z_STRVAL_P(ztmp)->val, Z_STRVAL_P(ztmp)->len);
}
}
/* }}} */ /* }}} */
static int static int
mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ mysqlnd_build_trace_args(zval *arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{ {
char **str; char **str;
int *len; int *len;
@ -64,20 +65,20 @@ mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_
* but that could cause some E_NOTICE and also damn long lines. * but that could cause some E_NOTICE and also damn long lines.
*/ */
switch (Z_TYPE_PP(arg)) { switch (Z_TYPE_P(arg)) {
case IS_NULL: case IS_NULL:
TRACE_APPEND_STR("NULL, "); TRACE_APPEND_STR("NULL, ");
break; break;
case IS_STRING: { case IS_STRING: {
int l_added; int l_added;
TRACE_APPEND_CHR('\''); TRACE_APPEND_CHR('\'');
if (Z_STRLEN_PP(arg) > 15) { if (Z_STRLEN_P(arg) > 15) {
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15); TRACE_APPEND_STRL(Z_STRVAL_P(arg), 15);
TRACE_APPEND_STR("...', "); TRACE_APPEND_STR("...', ");
l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */ l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
} else { } else {
l_added = Z_STRLEN_PP(arg); l_added = Z_STRLEN_P(arg);
TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added); TRACE_APPEND_STRL(Z_STRVAL_P(arg), l_added);
TRACE_APPEND_STR("', "); TRACE_APPEND_STR("', ");
l_added += 3 + 1; l_added += 3 + 1;
} }
@ -88,18 +89,17 @@ mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_
} }
break; break;
} }
case IS_BOOL: case IS_TRUE:
if (Z_LVAL_PP(arg)) {
TRACE_APPEND_STR("true, "); TRACE_APPEND_STR("true, ");
} else { break;
case IS_FALSE:
TRACE_APPEND_STR("false, "); TRACE_APPEND_STR("false, ");
}
break; break;
case IS_RESOURCE: case IS_RESOURCE:
TRACE_APPEND_STR("Resource id #"); TRACE_APPEND_STR("Resource id #");
/* break; */ /* break; */
case IS_LONG: { case IS_LONG: {
long lval = Z_LVAL_PP(arg); long lval = Z_LVAL_P(arg);
char s_tmp[MAX_LENGTH_OF_LONG + 1]; char s_tmp[MAX_LENGTH_OF_LONG + 1];
int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */ int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */
TRACE_APPEND_STRL(s_tmp, l_tmp); TRACE_APPEND_STRL(s_tmp, l_tmp);
@ -107,7 +107,7 @@ mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_
break; break;
} }
case IS_DOUBLE: { case IS_DOUBLE: {
double dval = Z_DVAL_PP(arg); double dval = Z_DVAL_P(arg);
char *s_tmp; char *s_tmp;
int l_tmp; int l_tmp;
@ -123,15 +123,15 @@ mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_
TRACE_APPEND_STR("Array, "); TRACE_APPEND_STR("Array, ");
break; break;
case IS_OBJECT: { case IS_OBJECT: {
char *class_name; zend_string *class_name;
zend_uint class_name_len; /* see #67299, may be removed now */
int dupl; int dupl = 0;
TRACE_APPEND_STR("Object("); TRACE_APPEND_STR("Object(");
dupl = zend_get_object_classname(*arg, (const char **)&class_name, &class_name_len TSRMLS_CC); class_name = zend_get_object_classname(Z_OBJ_P(arg) TSRMLS_CC);
TRACE_APPEND_STRL(class_name, class_name_len); TRACE_APPEND_STRL(class_name->val, class_name->len);
if (!dupl) { if (!dupl) {
efree(class_name); efree(class_name);
} }
@ -147,13 +147,13 @@ mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_
/* }}} */ /* }}} */
static int static int
mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ mysqlnd_build_trace_string(zval *frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{ {
char *s_tmp, **str; char *s_tmp, **str;
int *len, *num; int *len, *num;
long line; long line;
HashTable *ht = Z_ARRVAL_PP(frame); HashTable *ht = Z_ARRVAL_P(frame);
zval **file, **tmp; zval *zfile, *tmp, *zline;
uint * level; uint * level;
level = va_arg(args, uint *); level = va_arg(args, uint *);
@ -170,26 +170,27 @@ mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, z
sprintf(s_tmp, "#%d ", (*num)++); sprintf(s_tmp, "#%d ", (*num)++);
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
efree(s_tmp); efree(s_tmp);
if (zend_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) {
if (zend_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) { if ((zfile = zend_hash_str_find(ht, "file", sizeof("file"))) != NULL) {
line = Z_LVAL_PP(tmp); if ((zline = zend_hash_str_find(ht, "line", sizeof("line"))) != NULL) {
line = Z_LVAL_P(zline);
} else { } else {
line = 0; line = 0;
} }
s_tmp = emalloc(Z_STRLEN_PP(file) + MAX_LENGTH_OF_LONG + 4 + 1); s_tmp = emalloc(Z_STRLEN_P(zfile) + MAX_LENGTH_OF_LONG + 4 + 1);
sprintf(s_tmp, "%s(%ld): ", Z_STRVAL_PP(file), line); sprintf(s_tmp, "%s(%ld): ", Z_STR_P(zfile)->val, line);
TRACE_APPEND_STRL(s_tmp, strlen(s_tmp)); TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
efree(s_tmp); efree(s_tmp);
} else { } else {
TRACE_APPEND_STR("[internal function]: "); TRACE_APPEND_STR("[internal function]: ");
} }
TRACE_APPEND_KEY("class"); trace_append_key(ht, "class");
TRACE_APPEND_KEY("type"); trace_append_key(ht, "type");
TRACE_APPEND_KEY("function"); trace_append_key(ht, "function");
TRACE_APPEND_CHR('('); TRACE_APPEND_CHR('(');
if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) { if (zend_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) {
int last_len = *len; int last_len = *len;
zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len); zend_hash_apply_with_arguments(Z_ARRVAL_P(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len);
if (last_len != *len) { if (last_len != *len) {
*len -= 2; /* remove last ', ' */ *len -= 2; /* remove last ', ' */
} }

View file

@ -59,11 +59,11 @@ PHP_FUNCTION(readline_callback_handler_remove);
PHP_FUNCTION(readline_redisplay); PHP_FUNCTION(readline_redisplay);
PHP_FUNCTION(readline_on_new_line); PHP_FUNCTION(readline_on_new_line);
static zval *_prepped_callback = NULL; static zval _prepped_callback;
#endif #endif
static zval *_readline_completion = NULL; static zval _readline_completion;
static zval _readline_array; static zval _readline_array;
PHP_MINIT_FUNCTION(readline); PHP_MINIT_FUNCTION(readline);
@ -172,9 +172,13 @@ PHP_MINIT_FUNCTION(readline)
{ {
#if HAVE_LIBREADLINE #if HAVE_LIBREADLINE
/* libedit don't need this call which set the tty in cooked mode */ /* libedit don't need this call which set the tty in cooked mode */
using_history(); using_history();
#endif #endif
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU); ZVAL_UNDEF(&_readline_completion);
#if HAVE_RL_CALLBACK_READ_CHAR
ZVAL_UNDEF(&_prepped_callback);
#endif
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
} }
PHP_MSHUTDOWN_FUNCTION(readline) PHP_MSHUTDOWN_FUNCTION(readline)
@ -184,15 +188,13 @@ PHP_MSHUTDOWN_FUNCTION(readline)
PHP_RSHUTDOWN_FUNCTION(readline) PHP_RSHUTDOWN_FUNCTION(readline)
{ {
if (_readline_completion) { zval_dtor(&_readline_completion);
zval_dtor(_readline_completion); ZVAL_UNDEF(&_readline_completion);
FREE_ZVAL(_readline_completion);
}
#if HAVE_RL_CALLBACK_READ_CHAR #if HAVE_RL_CALLBACK_READ_CHAR
if (_prepped_callback) { if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove(); rl_callback_handler_remove();
zval_ptr_dtor(&_prepped_callback); zval_ptr_dtor(&_prepped_callback);
_prepped_callback = 0; ZVAL_UNDEF(&_prepped_callback);
} }
#endif #endif
@ -223,7 +225,7 @@ PHP_FUNCTION(readline)
if (! result) { if (! result) {
RETURN_FALSE; RETURN_FALSE;
} else { } else {
RETVAL_STRING(result,1); RETVAL_STRING(result);
free(result); free(result);
} }
} }
@ -237,11 +239,11 @@ PHP_FUNCTION(readline)
PHP_FUNCTION(readline_info) PHP_FUNCTION(readline_info)
{ {
char *what = NULL; char *what = NULL;
zval **value = NULL; zval *value = NULL;
int what_len, oldval; int what_len, oldval;
char *oldstr; 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; return;
} }
@ -269,9 +271,9 @@ PHP_FUNCTION(readline_info)
if (value) { if (value) {
/* XXX if (rl_line_buffer) free(rl_line_buffer); */ /* XXX if (rl_line_buffer) free(rl_line_buffer); */
convert_to_string_ex(value); 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")) { } else if (!strcasecmp(what, "point")) {
RETVAL_LONG(rl_point); RETVAL_LONG(rl_point);
} else if (!strcasecmp(what, "end")) { } else if (!strcasecmp(what, "end")) {
@ -283,20 +285,20 @@ PHP_FUNCTION(readline_info)
oldval = rl_done; oldval = rl_done;
if (value) { if (value) {
convert_to_long_ex(value); convert_to_long_ex(value);
rl_done = Z_LVAL_PP(value); rl_done = Z_LVAL_P(value);
} }
RETVAL_LONG(oldval); RETVAL_LONG(oldval);
} else if (!strcasecmp(what, "pending_input")) { } else if (!strcasecmp(what, "pending_input")) {
oldval = rl_pending_input; oldval = rl_pending_input;
if (value) { if (value) {
convert_to_string_ex(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); RETVAL_LONG(oldval);
} else if (!strcasecmp(what, "prompt")) { } else if (!strcasecmp(what, "prompt")) {
RETVAL_STRING(SAFE_STRING(rl_prompt),1); RETVAL_STRING(SAFE_STRING(rl_prompt));
} else if (!strcasecmp(what, "terminal_name")) { } else if (!strcasecmp(what, "terminal_name")) {
RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name),1); RETVAL_STRING((char *)SAFE_STRING(rl_terminal_name));
#endif #endif
#if HAVE_ERASE_EMPTY_LINE #if HAVE_ERASE_EMPTY_LINE
} else if (!strcasecmp(what, "erase_empty_line")) { } else if (!strcasecmp(what, "erase_empty_line")) {
@ -308,20 +310,20 @@ PHP_FUNCTION(readline_info)
RETVAL_LONG(oldval); RETVAL_LONG(oldval);
#endif #endif
} else if (!strcasecmp(what,"library_version")) { } 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")) { } else if (!strcasecmp(what, "readline_name")) {
oldstr = (char*)rl_readline_name; oldstr = (char*)rl_readline_name;
if (value) { if (value) {
/* XXX if (rl_readline_name) free(rl_readline_name); */ /* XXX if (rl_readline_name) free(rl_readline_name); */
convert_to_string_ex(value); 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")) { } else if (!strcasecmp(what, "attempted_completion_over")) {
oldval = rl_attempted_completion_over; oldval = rl_attempted_completion_over;
if (value) { if (value) {
convert_to_long_ex(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); RETVAL_LONG(oldval);
} }
@ -442,63 +444,50 @@ PHP_FUNCTION(readline_write_history)
static char *_readline_command_generator(const char *text, int state) static char *_readline_command_generator(const char *text, int state)
{ {
HashTable *myht = Z_ARRVAL(_readline_array); HashTable *myht = Z_ARRVAL(_readline_array);
zval **entry; zval *entry;
if (!state) { if (!state) {
zend_hash_internal_pointer_reset(myht); 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); zend_hash_move_forward(myht);
convert_to_string_ex(entry); convert_to_string_ex(entry);
if (strncmp (Z_STRVAL_PP(entry), text, strlen(text)) == 0) { if (strncmp (Z_STRVAL_P(entry), text, strlen(text)) == 0) {
return (strdup(Z_STRVAL_PP(entry))); return (strdup(Z_STRVAL_P(entry)));
} }
} }
return NULL; 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) { if (str) {
len = strlen(str); ZVAL_STRING(ret, (char*)str);
ZVAL_STRINGL(ret, (char*)str, len, 1);
} else { } else {
ZVAL_NULL(ret); ZVAL_NULL(ret);
} }
return ret;
} }
static zval *_readline_long_zval(long l) static void _readline_long_zval(zval *ret, long l)
{ {
zval *ret; ZVAL_LONG(ret, l);
MAKE_STD_ZVAL(ret);
Z_TYPE_P(ret) = IS_LONG;
Z_LVAL_P(ret) = l;
return ret;
} }
static char **_readline_completion_cb(const char *text, int start, int end) static char **_readline_completion_cb(const char *text, int start, int end)
{ {
zval *params[3]; zval params[3];
int i; int i;
char **matches = NULL; char **matches = NULL;
TSRMLS_FETCH(); TSRMLS_FETCH();
params[0]=_readline_string_zval(text); _readline_string_zval(&params[0], text);
params[1]=_readline_long_zval(start); _readline_long_zval(&params[1], start);
params[2]=_readline_long_zval(end); _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 (Z_TYPE(_readline_array) == IS_ARRAY) {
if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) { if (zend_hash_num_elements(Z_ARRVAL(_readline_array))) {
matches = rl_completion_matches(text,_readline_command_generator); 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) PHP_FUNCTION(readline_completion_function)
{ {
zval *arg = NULL; zval *arg = NULL;
char *name = NULL; zend_string *name = NULL;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg)) { if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg)) {
RETURN_FALSE; RETURN_FALSE;
} }
if (!zend_is_callable(arg, 0, &name TSRMLS_CC)) { if (!zend_is_callable(arg, 0, &name TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name->val);
efree(name); STR_RELEASE(name);
RETURN_FALSE; RETURN_FALSE;
} }
efree(name); STR_RELEASE(name);
if (_readline_completion) { zval_dtor(&_readline_completion);
zval_dtor(_readline_completion); ZVAL_DUP(&_readline_completion, arg);
FREE_ZVAL(_readline_completion);
}
MAKE_STD_ZVAL(_readline_completion);
*_readline_completion = *arg;
zval_copy_ctor(_readline_completion);
rl_attempted_completion_function = _readline_completion_cb; rl_attempted_completion_function = _readline_completion_cb;
if (rl_attempted_completion_function == NULL) { if (rl_attempted_completion_function == NULL) {
efree(name);
RETURN_FALSE; RETURN_FALSE;
} }
RETURN_TRUE; RETURN_TRUE;
@ -560,15 +542,15 @@ PHP_FUNCTION(readline_completion_function)
static void php_rl_callback_handler(char *the_line) static void php_rl_callback_handler(char *the_line)
{ {
zval *params[1]; zval params[1];
zval dummy; zval dummy;
TSRMLS_FETCH(); TSRMLS_FETCH();
ZVAL_NULL(&dummy); 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_ptr_dtor(&params[0]);
zval_dtor(&dummy); zval_dtor(&dummy);
@ -579,7 +561,7 @@ static void php_rl_callback_handler(char *the_line)
PHP_FUNCTION(readline_callback_handler_install) PHP_FUNCTION(readline_callback_handler_install)
{ {
zval *callback; zval *callback;
char *name = NULL; zend_string *name = NULL;
char *prompt; char *prompt;
int prompt_len; int prompt_len;
@ -588,20 +570,18 @@ PHP_FUNCTION(readline_callback_handler_install)
} }
if (!zend_is_callable(callback, 0, &name TSRMLS_CC)) { if (!zend_is_callable(callback, 0, &name TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name); php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not callable", name->val);
efree(name); STR_RELEASE(name);
RETURN_FALSE; RETURN_FALSE;
} }
efree(name); STR_RELEASE(name);
if (_prepped_callback) { if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove(); rl_callback_handler_remove();
zval_dtor(_prepped_callback); zval_dtor(&_prepped_callback);
FREE_ZVAL(_prepped_callback);
} }
ALLOC_ZVAL(_prepped_callback); ZVAL_DUP(&_prepped_callback, callback);
MAKE_COPY_ZVAL(&callback, _prepped_callback);
rl_callback_handler_install(prompt, php_rl_callback_handler); 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 */ Informs the readline callback interface that a character is ready for input */
PHP_FUNCTION(readline_callback_read_char) PHP_FUNCTION(readline_callback_read_char)
{ {
if (_prepped_callback) { if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_read_char(); rl_callback_read_char();
} }
} }
@ -623,11 +603,10 @@ PHP_FUNCTION(readline_callback_read_char)
Removes a previously installed callback handler and restores terminal settings */ Removes a previously installed callback handler and restores terminal settings */
PHP_FUNCTION(readline_callback_handler_remove) PHP_FUNCTION(readline_callback_handler_remove)
{ {
if (_prepped_callback) { if (Z_TYPE(_prepped_callback) != IS_UNDEF) {
rl_callback_handler_remove(); rl_callback_handler_remove();
zval_dtor(_prepped_callback); zval_dtor(&_prepped_callback);
FREE_ZVAL(_prepped_callback); ZVAL_UNDEF(&_prepped_callback);
_prepped_callback = 0;
RETURN_TRUE; RETURN_TRUE;
} }
RETURN_FALSE; RETURN_FALSE;

View file

@ -131,7 +131,7 @@ typedef enum {
outside, outside,
} php_code_type; } 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}; smart_str retval = {0};
char *prompt_spec = CLIR_G(prompt) ? CLIR_G(prompt) : DEFAULT_PROMPT; 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); } while (++prompt_spec && *prompt_spec);
smart_str_0(&retval); 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 valid_end = 1, last_valid_end;
int brackets_count = 0; 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) /* {{{ */ 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; ulong number;
if (!(*state % 2)) { 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) { while(zend_hash_has_more_elements(ht) == SUCCESS) {
zend_hash_get_current_key(ht, &name, &number, 0); zend_hash_get_current_key(ht, &name, &number, 0);
if (!textlen || !strncmp(name, text, textlen)) { if (!textlen || !strncmp(name->val, text, textlen)) {
if (pData) { if (pData) {
zend_hash_get_current_data(ht, pData); *pData = zend_hash_get_current_data_ptr(ht);
} }
zend_hash_move_forward(ht); zend_hash_move_forward(ht);
return name; return name->val;
} }
if (zend_hash_move_forward(ht) == FAILURE) { if (zend_hash_move_forward(ht) == FAILURE) {
break; break;
@ -433,7 +433,7 @@ static char *cli_completion_generator_var(const char *text, int textlen, int *st
{ {
char *retval, *tmp; 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) { if (retval) {
retval = malloc(strlen(tmp) + 2); retval = malloc(strlen(tmp) + 2);
retval[0] = '$'; 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); char *retval = cli_completion_generator_ht(text, textlen, state, ht, (void**)&func TSRMLS_CC);
if (retval) { if (retval) {
rl_completion_append_character = '('; rl_completion_append_character = '(';
retval = strdup(func->common.function_name); retval = strdup(func->common.function_name->val);
} }
return retval; 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) /* {{{ */ static char *cli_completion_generator_class(const char *text, int textlen, int *state TSRMLS_DC) /* {{{ */
{ {
zend_class_entry **pce; zend_class_entry *ce;
char *retval = cli_completion_generator_ht(text, textlen, state, EG(class_table), (void**)&pce TSRMLS_CC); char *retval = cli_completion_generator_ht(text, textlen, state, EG(class_table), (void**)&ce TSRMLS_CC);
if (retval) { if (retval) {
rl_completion_append_character = '\0'; rl_completion_append_character = '\0';
retval = strdup((*pce)->name); retval = strdup(ce->name->val);
} }
return retval; return retval;
@ -518,17 +518,18 @@ TODO:
} else if (text[0] == '#') { } else if (text[0] == '#') {
retval = cli_completion_generator_ini(text, textlen, &cli_completion_state TSRMLS_CC); retval = cli_completion_generator_ini(text, textlen, &cli_completion_state TSRMLS_CC);
} else { } else {
char *lc_text, *class_name, *class_name_end; char *lc_text, *class_name_end;
int class_name_len; int class_name_len;
zend_class_entry **pce = NULL; zend_string *class_name;
zend_class_entry *ce = NULL;
class_name_end = strstr(text, "::"); class_name_end = strstr(text, "::");
if (class_name_end) { if (class_name_end) {
class_name_len = class_name_end - text; class_name_len = class_name_end - text;
class_name = zend_str_tolower_dup(text, class_name_len); class_name = STR_ALLOC(class_name_len, 0);
class_name[class_name_len] = '\0'; /* not done automatically */ zend_str_tolower_copy(class_name->val, text, class_name_len);
if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) { if ((ce = zend_lookup_class(class_name TSRMLS_CC)) == NULL) {
efree(class_name); STR_RELEASE(class_name);
return NULL; return NULL;
} }
lc_text = zend_str_tolower_dup(class_name_end + 2, textlen - 2 - class_name_len); lc_text = zend_str_tolower_dup(class_name_end + 2, textlen - 2 - class_name_len);
@ -540,14 +541,14 @@ TODO:
switch (cli_completion_state) { switch (cli_completion_state) {
case 0: case 0:
case 1: 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) { if (retval) {
break; break;
} }
case 2: case 2:
case 3: case 3:
retval = cli_completion_generator_define(text, textlen, &cli_completion_state, pce ? &(*pce)->constants_table : EG(zend_constants) TSRMLS_CC); retval = cli_completion_generator_define(text, textlen, &cli_completion_state, ce ? &ce->constants_table : EG(zend_constants) TSRMLS_CC);
if (retval || pce) { if (retval || ce) {
break; break;
} }
case 4: case 4:
@ -559,13 +560,13 @@ TODO:
} }
efree(lc_text); efree(lc_text);
if (class_name_end) { 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; int len = class_name_len + 2 + strlen(retval) + 1;
char *tmp = malloc(len); char *tmp = malloc(len);
snprintf(tmp, len, "%s::%s", (*pce)->name, retval); snprintf(tmp, len, "%s::%s", ce->name->val, retval);
free(retval); free(retval);
retval = tmp; retval = tmp;
} }
@ -585,7 +586,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
char *line; char *line;
size_t size = 4096, pos = 0, len; size_t size = 4096, pos = 0, len;
char *code = emalloc(size); char *code = emalloc(size);
char *prompt = cli_get_prompt("php", '>' TSRMLS_CC); zend_string *prompt = cli_get_prompt("php", '>' TSRMLS_CC);
char *history_file; char *history_file;
if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) { 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); read_history(history_file);
EG(exit_status) = 0; EG(exit_status) = 0;
while ((line = readline(prompt)) != NULL) { while ((line = readline(prompt->val)) != NULL) {
if (strcmp(line, "exit") == 0 || strcmp(line, "quit") == 0) { if (strcmp(line, "exit") == 0 || strcmp(line, "quit") == 0) {
free(line); free(line);
break; break;
@ -623,17 +624,15 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
if (line[0] == '#') { if (line[0] == '#') {
char *param = strstr(&line[1], "="); char *param = strstr(&line[1], "=");
if (param) { if (param) {
char *cmd; zend_string *cmd;
uint cmd_len;
param++; param++;
cmd_len = param - &line[1] - 1; cmd = STR_INIT(&line[1], param - &line[1] - 1, 0);
cmd = estrndup(&line[1], cmd_len);
zend_alter_ini_entry_ex(cmd, cmd_len + 1, param, strlen(param), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); zend_alter_ini_entry_ex(cmd, param, strlen(param), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC);
efree(cmd); STR_RELEASE(cmd);
add_history(line); add_history(line);
efree(prompt); STR_RELEASE(prompt);
/* TODO: This might be wrong! */ /* TODO: This might be wrong! */
prompt = cli_get_prompt("php", '>' TSRMLS_CC); prompt = cli_get_prompt("php", '>' TSRMLS_CC);
continue; continue;
@ -654,7 +653,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
} }
free(line); free(line);
efree(prompt); STR_RELEASE(prompt);
if (!cli_is_valid_code(code, pos, &prompt TSRMLS_CC)) { if (!cli_is_valid_code(code, pos, &prompt TSRMLS_CC)) {
continue; continue;
@ -684,7 +683,7 @@ static int readline_shell_run(TSRMLS_D) /* {{{ */
write_history(history_file); write_history(history_file);
free(history_file); free(history_file);
efree(code); efree(code);
efree(prompt); STR_RELEASE(prompt);
return EG(exit_status); return EG(exit_status);
} }
/* }}} */ /* }}} */