diff options
author | Nikita Popov <nikic@php.net> | 2016-12-18 22:53:25 +0100 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2017-01-01 21:28:21 +0100 |
commit | f3f594a47d63e993595ad344614cee4a910305b1 (patch) | |
tree | 3c63c405034e4bc1523a55f30e9cad8addeab532 /ext | |
parent | 384e959a3a19afd898e2c4c4c6431aa273601057 (diff) | |
download | php-git-f3f594a47d63e993595ad344614cee4a910305b1.tar.gz |
Switch reflection to use smart_str
Instead of yet-another-smart-string-implementation.
Expand the smart_str API by:
* smart_str_extract() which gets a finalized zend_string* from a
smart_str, including insertion of the zero byte and handling of
the empty string case. This should be preferred over using
smart_str_0() in conjunction with str.s.
* smart_str_get_len() which gets the length of the smart_str with
handling of the empty string case.
Diffstat (limited to 'ext')
-rw-r--r-- | ext/reflection/php_reflection.c | 538 |
1 files changed, 227 insertions, 311 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index e89293ecfc..cbe76d2cac 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -42,6 +42,7 @@ #include "zend_generators.h" #include "zend_extensions.h" #include "zend_builtin_functions.h" +#include "zend_smart_str.h" #define reflection_update_property(object, name, value) do { \ zval member; \ @@ -103,75 +104,6 @@ PHPAPI zend_class_entry *reflection_zend_extension_ptr; #define REGISTER_REFLECTION_CLASS_CONST_LONG(class_name, const_name, value) \ zend_declare_class_constant_long(reflection_ ## class_name ## _ptr, const_name, sizeof(const_name)-1, (zend_long)value); -/* {{{ Smart string functions */ -typedef struct _string { - zend_string *buf; - size_t alloced; -} string; - -static void string_init(string *str) -{ - str->buf= zend_string_alloc(1024, 0); - str->alloced = 1024; - ZSTR_VAL(str->buf)[0] = '\0'; - ZSTR_LEN(str->buf) = 0; -} - -static string *string_printf(string *str, const char *format, ...) -{ - size_t len; - va_list arg; - char *s_tmp; - - va_start(arg, format); - len = zend_vspprintf(&s_tmp, 0, format, arg); - if (len) { - register size_t nlen = (ZSTR_LEN(str->buf) + 1 + len + (1024 - 1)) & ~(1024 - 1); - if (str->alloced < nlen) { - size_t old_len = ZSTR_LEN(str->buf); - str->alloced = nlen; - str->buf = zend_string_extend(str->buf, str->alloced, 0); - ZSTR_LEN(str->buf) = old_len; - } - memcpy(ZSTR_VAL(str->buf) + ZSTR_LEN(str->buf), s_tmp, len + 1); - ZSTR_LEN(str->buf) += len; - } - efree(s_tmp); - va_end(arg); - return str; -} - -static string *string_write(string *str, char *buf, size_t len) -{ - register size_t nlen = (ZSTR_LEN(str->buf) + 1 + len + (1024 - 1)) & ~(1024 - 1); - if (str->alloced < nlen) { - size_t old_len = ZSTR_LEN(str->buf); - str->alloced = nlen; - str->buf = zend_string_extend(str->buf, str->alloced, 0); - ZSTR_LEN(str->buf) = old_len; - } - memcpy(ZSTR_VAL(str->buf) + ZSTR_LEN(str->buf), buf, len); - ZSTR_LEN(str->buf) += len; - ZSTR_VAL(str->buf)[ZSTR_LEN(str->buf)] = '\0'; - return str; -} - -static string *string_append(string *str, string *append) -{ - if (ZSTR_LEN(append->buf) > 0) { - string_write(str, ZSTR_VAL(append->buf), ZSTR_LEN(append->buf)); - } - return str; -} - -static void string_free(string *str) -{ - zend_string_release(str->buf); - str->alloced = 0; - str->buf = NULL; -} -/* }}} */ - /* {{{ Object structure */ /* Struct for properties */ @@ -361,31 +293,31 @@ static zval *reflection_instantiate(zend_class_entry *pce, zval *object) /* {{{ } /* }}} */ -static void _const_string(string *str, char *name, zval *value, char *indent); -static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent); -static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent); -static void _class_const_string(string *str, char *name, zend_class_constant *c, char* indent); -static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent); -static void _extension_string(string *str, zend_module_entry *module, char *indent); -static void _zend_extension_string(string *str, zend_extension *extension, char *indent); +static void _const_string(smart_str *str, char *name, zval *value, char *indent); +static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent); +static void _property_string(smart_str *str, zend_property_info *prop, char *prop_name, char* indent); +static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char* indent); +static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent); +static void _extension_string(smart_str *str, zend_module_entry *module, char *indent); +static void _zend_extension_string(smart_str *str, zend_extension *extension, char *indent); /* {{{ _class_string */ -static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *indent) +static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent) { int count, count_static_props = 0, count_static_funcs = 0, count_shadow_props = 0; - string sub_indent; - string_init(&sub_indent); - string_printf(&sub_indent, "%s ", indent); + smart_str sub_indent = {0}; + smart_str_append_printf(&sub_indent, "%s ", indent); + smart_str_0(&sub_indent); /* TBD: Repair indenting of doc comment (or is this to be done in the parser?) */ if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) { - string_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment)); - string_write(str, "\n", 1); + smart_str_append_printf(str, "%s%s", indent, ZSTR_VAL(ce->info.user.doc_comment)); + smart_str_appendc(str, '\n'); } if (obj && Z_TYPE_P(obj) == IS_OBJECT) { - string_printf(str, "%sObject of class [ ", indent); + smart_str_append_printf(str, "%sObject of class [ ", indent); } else { char *kind = "Class"; if (ce->ce_flags & ZEND_ACC_INTERFACE) { @@ -393,67 +325,67 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } else if (ce->ce_flags & ZEND_ACC_TRAIT) { kind = "Trait"; } - string_printf(str, "%s%s [ ", indent, kind); + smart_str_append_printf(str, "%s%s [ ", indent, kind); } - string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal"); + smart_str_append_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : "<internal"); if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) { - string_printf(str, ":%s", ce->info.internal.module->name); + smart_str_append_printf(str, ":%s", ce->info.internal.module->name); } - string_printf(str, "> "); + smart_str_append_printf(str, "> "); if (ce->get_iterator != NULL) { - string_printf(str, "<iterateable> "); + smart_str_append_printf(str, "<iterateable> "); } if (ce->ce_flags & ZEND_ACC_INTERFACE) { - string_printf(str, "interface "); + smart_str_append_printf(str, "interface "); } else if (ce->ce_flags & ZEND_ACC_TRAIT) { - string_printf(str, "trait "); + smart_str_append_printf(str, "trait "); } else { if (ce->ce_flags & (ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { - string_printf(str, "abstract "); + smart_str_append_printf(str, "abstract "); } if (ce->ce_flags & ZEND_ACC_FINAL) { - string_printf(str, "final "); + smart_str_append_printf(str, "final "); } - string_printf(str, "class "); + smart_str_append_printf(str, "class "); } - string_printf(str, "%s", ZSTR_VAL(ce->name)); + smart_str_append_printf(str, "%s", ZSTR_VAL(ce->name)); if (ce->parent) { - string_printf(str, " extends %s", ZSTR_VAL(ce->parent->name)); + smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->parent->name)); } if (ce->num_interfaces) { uint32_t i; if (ce->ce_flags & ZEND_ACC_INTERFACE) { - string_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name)); + smart_str_append_printf(str, " extends %s", ZSTR_VAL(ce->interfaces[0]->name)); } else { - string_printf(str, " implements %s", ZSTR_VAL(ce->interfaces[0]->name)); + smart_str_append_printf(str, " implements %s", ZSTR_VAL(ce->interfaces[0]->name)); } for (i = 1; i < ce->num_interfaces; ++i) { - string_printf(str, ", %s", ZSTR_VAL(ce->interfaces[i]->name)); + smart_str_append_printf(str, ", %s", ZSTR_VAL(ce->interfaces[i]->name)); } } - string_printf(str, " ] {\n"); + smart_str_append_printf(str, " ] {\n"); /* The information where a class is declared is only available for user classes */ if (ce->type == ZEND_USER_CLASS) { - string_printf(str, "%s @@ %s %d-%d\n", indent, ZSTR_VAL(ce->info.user.filename), + smart_str_append_printf(str, "%s @@ %s %d-%d\n", indent, ZSTR_VAL(ce->info.user.filename), ce->info.user.line_start, ce->info.user.line_end); } /* Constants */ - string_printf(str, "\n"); + smart_str_append_printf(str, "\n"); count = zend_hash_num_elements(&ce->constants_table); - string_printf(str, "%s - Constants [%d] {\n", indent, count); + smart_str_append_printf(str, "%s - Constants [%d] {\n", indent, count); if (count > 0) { zend_string *key; zend_class_constant *c; ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) { - _class_const_string(str, ZSTR_VAL(key), c, ZSTR_VAL(sub_indent.buf)); + _class_const_string(str, ZSTR_VAL(key), c, ZSTR_VAL(sub_indent.s)); } ZEND_HASH_FOREACH_END(); } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); /* Static properties */ /* counting static properties */ @@ -471,17 +403,17 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* static properties */ - string_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); + smart_str_append_printf(str, "\n%s - Static properties [%d] {\n", indent, count_static_props); if (count_static_props > 0) { zend_property_info *prop; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.s)); } } ZEND_HASH_FOREACH_END(); } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); /* Static methods */ /* counting static methods */ @@ -499,7 +431,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } /* static methods */ - string_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); + smart_str_append_printf(str, "\n%s - Static methods [%d] {", indent, count_static_funcs); if (count_static_funcs > 0) { zend_function *mptr; @@ -507,52 +439,50 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in if (mptr->common.fn_flags & ZEND_ACC_STATIC && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) { - string_printf(str, "\n"); - _function_string(str, mptr, ce, ZSTR_VAL(sub_indent.buf)); + smart_str_append_printf(str, "\n"); + _function_string(str, mptr, ce, ZSTR_VAL(sub_indent.s)); } } ZEND_HASH_FOREACH_END(); } else { - string_printf(str, "\n"); + smart_str_append_printf(str, "\n"); } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); /* Default/Implicit properties */ count = zend_hash_num_elements(&ce->properties_info) - count_static_props - count_shadow_props; - string_printf(str, "\n%s - Properties [%d] {\n", indent, count); + smart_str_append_printf(str, "\n%s - Properties [%d] {\n", indent, count); if (count > 0) { zend_property_info *prop; ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) { if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) { - _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.buf)); + _property_string(str, prop, NULL, ZSTR_VAL(sub_indent.s)); } } ZEND_HASH_FOREACH_END(); } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); if (obj && Z_TYPE_P(obj) == IS_OBJECT && Z_OBJ_HT_P(obj)->get_properties) { - string dyn; HashTable *properties = Z_OBJ_HT_P(obj)->get_properties(obj); zend_string *prop_name; + smart_str prop_str = {0}; - string_init(&dyn); count = 0; - if (properties && zend_hash_num_elements(properties)) { ZEND_HASH_FOREACH_STR_KEY(properties, prop_name) { if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) { /* skip all private and protected properties */ if (!zend_hash_exists(&ce->properties_info, prop_name)) { count++; - _property_string(&dyn, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent.buf)); + _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent.s)); } } } ZEND_HASH_FOREACH_END(); } - string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count); - string_append(str, &dyn); - string_printf(str, "%s }\n", indent); - string_free(&dyn); + smart_str_append_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count); + smart_str_append_smart_str(str, &prop_str); + smart_str_append_printf(str, "%s }\n", indent); + smart_str_free(&prop_str); } /* Non static methods */ @@ -560,11 +490,9 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in if (count > 0) { zend_function *mptr; zend_string *key; - string dyn; + smart_str method_str = {0}; count = 0; - string_init(&dyn); - ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) { if ((mptr->common.fn_flags & ZEND_ACC_STATIC) == 0 && ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) == 0 || mptr->common.scope == ce)) @@ -587,40 +515,40 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in } else { closure = NULL; } - string_printf(&dyn, "\n"); - _function_string(&dyn, mptr, ce, ZSTR_VAL(sub_indent.buf)); + smart_str_appendc(&method_str, '\n'); + _function_string(&method_str, mptr, ce, ZSTR_VAL(sub_indent.s)); count++; _free_function(closure); } } } ZEND_HASH_FOREACH_END(); - string_printf(str, "\n%s - Methods [%d] {", indent, count); + smart_str_append_printf(str, "\n%s - Methods [%d] {", indent, count); + smart_str_append_smart_str(str, &method_str); if (!count) { - string_printf(str, "\n"); + smart_str_append_printf(str, "\n"); } - string_append(str, &dyn); - string_free(&dyn); + smart_str_free(&method_str); } else { - string_printf(str, "\n%s - Methods [0] {\n", indent); + smart_str_append_printf(str, "\n%s - Methods [0] {\n", indent); } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); - string_printf(str, "%s}\n", indent); - string_free(&sub_indent); + smart_str_append_printf(str, "%s}\n", indent); + smart_str_free(&sub_indent); } /* }}} */ /* {{{ _const_string */ -static void _const_string(string *str, char *name, zval *value, char *indent) +static void _const_string(smart_str *str, char *name, zval *value, char *indent) { char *type = zend_zval_type_name(value); if (Z_TYPE_P(value) == IS_ARRAY) { - string_printf(str, "%s Constant [ %s %s ] { Array }\n", + smart_str_append_printf(str, "%s Constant [ %s %s ] { Array }\n", indent, type, name); } else { zend_string *value_str = zval_get_string(value); - string_printf(str, "%s Constant [ %s %s ] { %s }\n", + smart_str_append_printf(str, "%s Constant [ %s %s ] { %s }\n", indent, type, name, ZSTR_VAL(value_str)); zend_string_release(value_str); } @@ -628,7 +556,7 @@ static void _const_string(string *str, char *name, zval *value, char *indent) /* }}} */ /* {{{ _class_const_string */ -static void _class_const_string(string *str, char *name, zend_class_constant *c, char *indent) +static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char *indent) { char *visibility = zend_visibility_string(Z_ACCESS_FLAGS(c->value)); char *type; @@ -637,12 +565,12 @@ static void _class_const_string(string *str, char *name, zend_class_constant *c, type = zend_zval_type_name(&c->value); if (Z_TYPE(c->value) == IS_ARRAY) { - string_printf(str, "%sConstant [ %s %s %s ] { Array }\n", + smart_str_append_printf(str, "%sConstant [ %s %s %s ] { Array }\n", indent, visibility, type, name); } else { zend_string *value_str = zval_get_string(&c->value); - string_printf(str, "%sConstant [ %s %s %s ] { %s }\n", + smart_str_append_printf(str, "%sConstant [ %s %s %s ] { %s }\n", indent, visibility, type, name, ZSTR_VAL(value_str)); zend_string_release(value_str); @@ -670,81 +598,81 @@ static zend_op* _get_recv_op(zend_op_array *op_array, uint32_t offset) /* }}} */ /* {{{ _parameter_string */ -static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg_info *arg_info, uint32_t offset, zend_bool required, char* indent) +static void _parameter_string(smart_str *str, zend_function *fptr, struct _zend_arg_info *arg_info, uint32_t offset, zend_bool required, char* indent) { - string_printf(str, "Parameter #%d [ ", offset); + smart_str_append_printf(str, "Parameter #%d [ ", offset); if (!required) { - string_printf(str, "<optional> "); + smart_str_append_printf(str, "<optional> "); } else { - string_printf(str, "<required> "); + smart_str_append_printf(str, "<required> "); } if (arg_info->class_name) { - string_printf(str, "%s ", + smart_str_append_printf(str, "%s ", (fptr->type == ZEND_INTERNAL_FUNCTION && !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ? ((zend_internal_arg_info*)arg_info)->class_name : ZSTR_VAL(arg_info->class_name)); if (arg_info->allow_null) { - string_printf(str, "or NULL "); + smart_str_append_printf(str, "or NULL "); } } else if (arg_info->type_hint) { - string_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint)); + smart_str_append_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint)); if (arg_info->allow_null) { - string_printf(str, "or NULL "); + smart_str_append_printf(str, "or NULL "); } } if (arg_info->pass_by_reference) { - string_write(str, "&", sizeof("&")-1); + smart_str_appendc(str, '&'); } if (arg_info->is_variadic) { - string_write(str, "...", sizeof("...")-1); + smart_str_appends(str, "..."); } if (arg_info->name) { - string_printf(str, "$%s", + smart_str_append_printf(str, "$%s", (fptr->type == ZEND_INTERNAL_FUNCTION && !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ? ((zend_internal_arg_info*)arg_info)->name : ZSTR_VAL(arg_info->name)); } else { - string_printf(str, "$param%d", offset); + smart_str_append_printf(str, "$param%d", offset); } if (fptr->type == ZEND_USER_FUNCTION && !required) { zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset); if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { zval zv; - string_write(str, " = ", sizeof(" = ")-1); + smart_str_appends(str, " = "); ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2)); zval_update_constant_ex(&zv, fptr->common.scope); if (Z_TYPE(zv) == IS_TRUE) { - string_write(str, "true", sizeof("true")-1); + smart_str_appends(str, "true"); } else if (Z_TYPE(zv) == IS_FALSE) { - string_write(str, "false", sizeof("false")-1); + smart_str_appends(str, "false"); } else if (Z_TYPE(zv) == IS_NULL) { - string_write(str, "NULL", sizeof("NULL")-1); + smart_str_appends(str, "NULL"); } else if (Z_TYPE(zv) == IS_STRING) { - string_write(str, "'", sizeof("'")-1); - string_write(str, Z_STRVAL(zv), MIN(Z_STRLEN(zv), 15)); + smart_str_appendc(str, '\''); + smart_str_appendl(str, Z_STRVAL(zv), MIN(Z_STRLEN(zv), 15)); if (Z_STRLEN(zv) > 15) { - string_write(str, "...", sizeof("...")-1); + smart_str_appends(str, "..."); } - string_write(str, "'", sizeof("'")-1); + smart_str_appendc(str, '\''); } else if (Z_TYPE(zv) == IS_ARRAY) { - string_write(str, "Array", sizeof("Array")-1); + smart_str_appends(str, "Array"); } else { zend_string *zv_str = zval_get_string(&zv); - string_write(str, ZSTR_VAL(zv_str), ZSTR_LEN(zv_str)); + smart_str_append(str, zv_str); zend_string_release(zv_str); } zval_ptr_dtor(&zv); } } - string_write(str, " ]", sizeof(" ]")-1); + smart_str_appends(str, " ]"); } /* }}} */ /* {{{ _function_parameter_string */ -static void _function_parameter_string(string *str, zend_function *fptr, char* indent) +static void _function_parameter_string(smart_str *str, zend_function *fptr, char* indent) { struct _zend_arg_info *arg_info = fptr->common.arg_info; uint32_t i, num_args, num_required = fptr->common.required_num_args; @@ -757,20 +685,20 @@ static void _function_parameter_string(string *str, zend_function *fptr, char* i if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) { num_args++; } - string_printf(str, "\n"); - string_printf(str, "%s- Parameters [%d] {\n", indent, num_args); + smart_str_appendc(str, '\n'); + smart_str_append_printf(str, "%s- Parameters [%d] {\n", indent, num_args); for (i = 0; i < num_args; i++) { - string_printf(str, "%s ", indent); + smart_str_append_printf(str, "%s ", indent); _parameter_string(str, fptr, arg_info, i, i < num_required, indent); - string_write(str, "\n", sizeof("\n")-1); + smart_str_appendc(str, '\n'); arg_info++; } - string_printf(str, "%s}\n", indent); + smart_str_append_printf(str, "%s}\n", indent); } /* }}} */ /* {{{ _function_closure_string */ -static void _function_closure_string(string *str, zend_function *fptr, char* indent) +static void _function_closure_string(smart_str *str, zend_function *fptr, char* indent) { uint32_t i, count; zend_string *key; @@ -787,20 +715,20 @@ static void _function_closure_string(string *str, zend_function *fptr, char* ind return; } - string_printf(str, "\n"); - string_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables)); + smart_str_append_printf(str, "\n"); + smart_str_append_printf(str, "%s- Bound Variables [%d] {\n", indent, zend_hash_num_elements(static_variables)); i = 0; ZEND_HASH_FOREACH_STR_KEY(static_variables, key) { - string_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, ZSTR_VAL(key)); + smart_str_append_printf(str, "%s Variable #%d [ $%s ]\n", indent, i++, ZSTR_VAL(key)); } ZEND_HASH_FOREACH_END(); - string_printf(str, "%s}\n", indent); + smart_str_append_printf(str, "%s}\n", indent); } /* }}} */ /* {{{ _function_string */ -static void _function_string(string *str, zend_function *fptr, zend_class_entry *scope, char* indent) +static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent) { - string param_indent; + smart_str param_indent = {0}; zend_function *overwrites; zend_string *lc_name; size_t lc_name_len; @@ -810,190 +738,190 @@ static void _function_string(string *str, zend_function *fptr, zend_class_entry * swallowed, leading to an unaligned comment. */ if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) { - string_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment)); + smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment)); } - string_write(str, indent, strlen(indent)); - string_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ ")); - string_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal"); + smart_str_appendl(str, indent, strlen(indent)); + smart_str_append_printf(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ ")); + smart_str_append_printf(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal"); if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) { - string_printf(str, ", deprecated"); + smart_str_appends(str, ", deprecated"); } if (fptr->type == ZEND_INTERNAL_FUNCTION && ((zend_internal_function*)fptr)->module) { - string_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name); + smart_str_append_printf(str, ":%s", ((zend_internal_function*)fptr)->module->name); } if (scope && fptr->common.scope) { if (fptr->common.scope != scope) { - string_printf(str, ", inherits %s", ZSTR_VAL(fptr->common.scope->name)); + smart_str_append_printf(str, ", inherits %s", ZSTR_VAL(fptr->common.scope->name)); } else if (fptr->common.scope->parent) { lc_name_len = ZSTR_LEN(fptr->common.function_name); lc_name = zend_string_alloc(lc_name_len, 0); zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(fptr->common.function_name), lc_name_len); if ((overwrites = zend_hash_find_ptr(&fptr->common.scope->parent->function_table, lc_name)) != NULL) { if (fptr->common.scope != overwrites->common.scope) { - string_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name)); + smart_str_append_printf(str, ", overwrites %s", ZSTR_VAL(overwrites->common.scope->name)); } } efree(lc_name); } } if (fptr->common.prototype && fptr->common.prototype->common.scope) { - string_printf(str, ", prototype %s", ZSTR_VAL(fptr->common.prototype->common.scope->name)); + smart_str_append_printf(str, ", prototype %s", ZSTR_VAL(fptr->common.prototype->common.scope->name)); } if (fptr->common.fn_flags & ZEND_ACC_CTOR) { - string_printf(str, ", ctor"); + smart_str_appends(str, ", ctor"); } if (fptr->common.fn_flags & ZEND_ACC_DTOR) { - string_printf(str, ", dtor"); + smart_str_appends(str, ", dtor"); } - string_printf(str, "> "); + smart_str_appends(str, "> "); if (fptr->common.fn_flags & ZEND_ACC_ABSTRACT) { - string_printf(str, "abstract "); + smart_str_appends(str, "abstract "); } if (fptr->common.fn_flags & ZEND_ACC_FINAL) { - string_printf(str, "final "); + smart_str_appends(str, "final "); } if (fptr->common.fn_flags & ZEND_ACC_STATIC) { - string_printf(str, "static "); + smart_str_appends(str, "static "); } if (fptr->common.scope) { /* These are mutually exclusive */ switch (fptr->common.fn_flags & ZEND_ACC_PPP_MASK) { case ZEND_ACC_PUBLIC: - string_printf(str, "public "); + smart_str_appends(str, "public "); break; case ZEND_ACC_PRIVATE: - string_printf(str, "private "); + smart_str_appends(str, "private "); break; case ZEND_ACC_PROTECTED: - string_printf(str, "protected "); + smart_str_appends(str, "protected "); break; default: - string_printf(str, "<visibility error> "); + smart_str_appends(str, "<visibility error> "); break; } - string_printf(str, "method "); + smart_str_appends(str, "method "); } else { - string_printf(str, "function "); + smart_str_appends(str, "function "); } if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) { - string_printf(str, "&"); + smart_str_appendc(str, '&'); } - string_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name)); + smart_str_append_printf(str, "%s ] {\n", ZSTR_VAL(fptr->common.function_name)); /* The information where a function is declared is only available for user classes */ if (fptr->type == ZEND_USER_FUNCTION) { - string_printf(str, "%s @@ %s %d - %d\n", indent, + smart_str_append_printf(str, "%s @@ %s %d - %d\n", indent, ZSTR_VAL(fptr->op_array.filename), fptr->op_array.line_start, fptr->op_array.line_end); } - string_init(¶m_indent); - string_printf(¶m_indent, "%s ", indent); + smart_str_append_printf(¶m_indent, "%s ", indent); + smart_str_0(¶m_indent); if (fptr->common.fn_flags & ZEND_ACC_CLOSURE) { - _function_closure_string(str, fptr, ZSTR_VAL(param_indent.buf)); + _function_closure_string(str, fptr, ZSTR_VAL(param_indent.s)); } - _function_parameter_string(str, fptr, ZSTR_VAL(param_indent.buf)); - string_free(¶m_indent); + _function_parameter_string(str, fptr, ZSTR_VAL(param_indent.s)); + smart_str_free(¶m_indent); if (fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) { - string_printf(str, " %s- Return [ ", indent); + smart_str_append_printf(str, " %s- Return [ ", indent); if (fptr->common.arg_info[-1].class_name) { - string_printf(str, "%s ", + smart_str_append_printf(str, "%s ", (fptr->type == ZEND_INTERNAL_FUNCTION && !(fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO)) ? ((zend_internal_arg_info*)(fptr->common.arg_info - 1))->class_name : ZSTR_VAL(fptr->common.arg_info[-1].class_name)); if (fptr->common.arg_info[-1].allow_null) { - string_printf(str, "or NULL "); + smart_str_appends(str, "or NULL "); } } else if (fptr->common.arg_info[-1].type_hint) { - string_printf(str, "%s ", zend_get_type_by_const(fptr->common.arg_info[-1].type_hint)); + smart_str_append_printf(str, "%s ", zend_get_type_by_const(fptr->common.arg_info[-1].type_hint)); if (fptr->common.arg_info[-1].allow_null) { - string_printf(str, "or NULL "); + smart_str_appends(str, "or NULL "); } } - string_printf(str, "]\n"); + smart_str_appends(str, "]\n"); } - string_printf(str, "%s}\n", indent); + smart_str_append_printf(str, "%s}\n", indent); } /* }}} */ /* {{{ _property_string */ -static void _property_string(string *str, zend_property_info *prop, char *prop_name, char* indent) +static void _property_string(smart_str *str, zend_property_info *prop, char *prop_name, char* indent) { const char *class_name; - string_printf(str, "%sProperty [ ", indent); + smart_str_append_printf(str, "%sProperty [ ", indent); if (!prop) { - string_printf(str, "<dynamic> public $%s", prop_name); + smart_str_append_printf(str, "<dynamic> public $%s", prop_name); } else { if (!(prop->flags & ZEND_ACC_STATIC)) { if (prop->flags & ZEND_ACC_IMPLICIT_PUBLIC) { - string_write(str, "<implicit> ", sizeof("<implicit> ") - 1); + smart_str_appends(str, "<implicit> "); } else { - string_write(str, "<default> ", sizeof("<default> ") - 1); + smart_str_appends(str, "<default> "); } } /* These are mutually exclusive */ switch (prop->flags & ZEND_ACC_PPP_MASK) { case ZEND_ACC_PUBLIC: - string_printf(str, "public "); + smart_str_appends(str, "public "); break; case ZEND_ACC_PRIVATE: - string_printf(str, "private "); + smart_str_appends(str, "private "); break; case ZEND_ACC_PROTECTED: - string_printf(str, "protected "); + smart_str_appends(str, "protected "); break; } if(prop->flags & ZEND_ACC_STATIC) { - string_printf(str, "static "); + smart_str_appends(str, "static "); } zend_unmangle_property_name(prop->name, &class_name, (const char**)&prop_name); - string_printf(str, "$%s", prop_name); + smart_str_append_printf(str, "$%s", prop_name); } - string_printf(str, " ]\n"); + smart_str_appends(str, " ]\n"); } /* }}} */ static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { zend_ini_entry *ini_entry = (zend_ini_entry*)Z_PTR_P(el); - string *str = va_arg(args, string *); + smart_str *str = va_arg(args, smart_str *); char *indent = va_arg(args, char *); int number = va_arg(args, int); char *comma = ""; if (number == ini_entry->module_number) { - string_printf(str, " %sEntry [ %s <", indent, ZSTR_VAL(ini_entry->name)); + smart_str_append_printf(str, " %sEntry [ %s <", indent, ZSTR_VAL(ini_entry->name)); if (ini_entry->modifiable == ZEND_INI_ALL) { - string_printf(str, "ALL"); + smart_str_appends(str, "ALL"); } else { if (ini_entry->modifiable & ZEND_INI_USER) { - string_printf(str, "USER"); + smart_str_appends(str, "USER"); comma = ","; } if (ini_entry->modifiable & ZEND_INI_PERDIR) { - string_printf(str, "%sPERDIR", comma); + smart_str_append_printf(str, "%sPERDIR", comma); comma = ","; } if (ini_entry->modifiable & ZEND_INI_SYSTEM) { - string_printf(str, "%sSYSTEM", comma); + smart_str_append_printf(str, "%sSYSTEM", comma); } } - string_printf(str, "> ]\n"); - string_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ZSTR_VAL(ini_entry->value) : ""); + smart_str_appends(str, "> ]\n"); + smart_str_append_printf(str, " %s Current = '%s'\n", indent, ini_entry->value ? ZSTR_VAL(ini_entry->value) : ""); if (ini_entry->modified) { - string_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : ""); + smart_str_append_printf(str, " %s Default = '%s'\n", indent, ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : ""); } - string_printf(str, " %s}\n", indent); + smart_str_append_printf(str, " %s}\n", indent); } return ZEND_HASH_APPLY_KEEP; } @@ -1002,7 +930,7 @@ static int _extension_ini_string(zval *el, int num_args, va_list args, zend_hash static int _extension_class_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { zend_class_entry *ce = (zend_class_entry*)Z_PTR_P(el); - string *str = va_arg(args, string *); + smart_str *str = va_arg(args, smart_str *); char *indent = va_arg(args, char *); struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*); int *num_classes = va_arg(args, int*); @@ -1010,7 +938,7 @@ static int _extension_class_string(zval *el, int num_args, va_list args, zend_ha if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module && !strcasecmp(ce->info.internal.module->name, module->name)) { /* dump class if it is not an alias */ if (!zend_binary_strcasecmp(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), ZSTR_VAL(hash_key->key), ZSTR_LEN(hash_key->key))) { - string_printf(str, "\n"); + smart_str_append_printf(str, "\n"); _class_string(str, ce, NULL, indent); (*num_classes)++; } @@ -1022,7 +950,7 @@ static int _extension_class_string(zval *el, int num_args, va_list args, zend_ha static int _extension_const_string(zval *el, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { zend_constant *constant = (zend_constant*)Z_PTR_P(el); - string *str = va_arg(args, string *); + smart_str *str = va_arg(args, smart_str *); char *indent = va_arg(args, char *); struct _zend_module_entry *module = va_arg(args, struct _zend_module_entry*); int *num_classes = va_arg(args, int*); @@ -1035,78 +963,76 @@ static int _extension_const_string(zval *el, int num_args, va_list args, zend_ha } /* }}} */ -static void _extension_string(string *str, zend_module_entry *module, char *indent) /* {{{ */ +static void _extension_string(smart_str *str, zend_module_entry *module, char *indent) /* {{{ */ { - string_printf(str, "%sExtension [ ", indent); + smart_str_append_printf(str, "%sExtension [ ", indent); if (module->type == MODULE_PERSISTENT) { - string_printf(str, "<persistent>"); + smart_str_appends(str, "<persistent>"); } if (module->type == MODULE_TEMPORARY) { - string_printf(str, "<temporary>" ); + smart_str_appends(str, "<temporary>" ); } - string_printf(str, " extension #%d %s version %s ] {\n", + smart_str_append_printf(str, " extension #%d %s version %s ] {\n", module->module_number, module->name, (module->version == NO_VERSION_YET) ? "<no_version>" : module->version); if (module->deps) { const zend_module_dep* dep = module->deps; - string_printf(str, "\n - Dependencies {\n"); + smart_str_appends(str, "\n - Dependencies {\n"); while(dep->name) { - string_printf(str, "%s Dependency [ %s (", indent, dep->name); + smart_str_append_printf(str, "%s Dependency [ %s (", indent, dep->name); switch(dep->type) { case MODULE_DEP_REQUIRED: - string_write(str, "Required", sizeof("Required") - 1); + smart_str_appends(str, "Required"); break; case MODULE_DEP_CONFLICTS: - string_write(str, "Conflicts", sizeof("Conflicts") - 1); + smart_str_appends(str, "Conflicts"); break; case MODULE_DEP_OPTIONAL: - string_write(str, "Optional", sizeof("Optional") - 1); + smart_str_appends(str, "Optional"); break; default: - string_write(str, "Error", sizeof("Error") - 1); /* shouldn't happen */ + smart_str_appends(str, "Error"); /* shouldn't happen */ break; } if (dep->rel) { - string_printf(str, " %s", dep->rel); + smart_str_append_printf(str, " %s", dep->rel); } if (dep->version) { - string_printf(str, " %s", dep->version); + smart_str_append_printf(str, " %s", dep->version); } - string_write(str, ") ]\n", sizeof(") ]\n") - 1); + smart_str_appends(str, ") ]\n"); dep++; } - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); } { - string str_ini; - string_init(&str_ini); + smart_str str_ini = {0}; zend_hash_apply_with_arguments(EG(ini_directives), (apply_func_args_t) _extension_ini_string, 3, &str_ini, indent, module->module_number); - if (ZSTR_LEN(str_ini.buf) > 0) { - string_printf(str, "\n - INI {\n"); - string_append(str, &str_ini); - string_printf(str, "%s }\n", indent); + if (smart_str_get_len(&str_ini) > 0) { + smart_str_append_printf(str, "\n - INI {\n"); + smart_str_append_smart_str(str, &str_ini); + smart_str_append_printf(str, "%s }\n", indent); } - string_free(&str_ini); + smart_str_free(&str_ini); } { - string str_constants; + smart_str str_constants = {0}; int num_constants = 0; - string_init(&str_constants); zend_hash_apply_with_arguments(EG(zend_constants), (apply_func_args_t) _extension_const_string, 4, &str_constants, indent, module, &num_constants); if (num_constants) { - string_printf(str, "\n - Constants [%d] {\n", num_constants); - string_append(str, &str_constants); - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "\n - Constants [%d] {\n", num_constants); + smart_str_append_smart_str(str, &str_constants); + smart_str_append_printf(str, "%s }\n", indent); } - string_free(&str_constants); + smart_str_free(&str_constants); } { @@ -1117,57 +1043,55 @@ static void _extension_string(string *str, zend_module_entry *module, char *inde if (fptr->common.type==ZEND_INTERNAL_FUNCTION && fptr->internal_function.module == module) { if (first) { - string_printf(str, "\n - Functions {\n"); + smart_str_append_printf(str, "\n - Functions {\n"); first = 0; } _function_string(str, fptr, NULL, " "); } } ZEND_HASH_FOREACH_END(); if (!first) { - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "%s }\n", indent); } } { - string str_classes; - string sub_indent; + smart_str str_classes = {0}; + smart_str sub_indent = {0}; int num_classes = 0; - string_init(&sub_indent); - string_printf(&sub_indent, "%s ", indent); - string_init(&str_classes); - zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, ZSTR_VAL(sub_indent.buf), module, &num_classes); + smart_str_append_printf(&sub_indent, "%s ", indent); + zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) _extension_class_string, 4, &str_classes, ZSTR_VAL(sub_indent.s), module, &num_classes); if (num_classes) { - string_printf(str, "\n - Classes [%d] {", num_classes); - string_append(str, &str_classes); - string_printf(str, "%s }\n", indent); + smart_str_append_printf(str, "\n - Classes [%d] {", num_classes); + smart_str_append_smart_str(str, &str_classes); + smart_str_append_printf(str, "%s }\n", indent); } - string_free(&str_classes); - string_free(&sub_indent); + smart_str_free(&str_classes); + smart_str_free(&sub_indent); } - string_printf(str, "%s}\n", indent); + smart_str_append_printf(str, "%s}\n", indent); } /* }}} */ -static void _zend_extension_string(string *str, zend_extension *extension, char *indent) /* {{{ */ +static void _zend_extension_string(smart_str *str, zend_extension *extension, char *indent) /* {{{ */ { - string_printf(str, "%sZend Extension [ %s ", indent, extension->name); + smart_str_append_printf(str, "%sZend Extension [ %s ", indent, extension->name); if (extension->version) { - string_printf(str, "%s ", extension->version); + smart_str_append_printf(str, "%s ", extension->version); } if (extension->copyright) { - string_printf(str, "%s ", extension->copyright); + smart_str_append_printf(str, "%s ", extension->copyright); } if (extension->author) { - string_printf(str, "by %s ", extension->author); + smart_str_append_printf(str, "by %s ", extension->author); } if (extension->URL) { - string_printf(str, "<%s> ", extension->URL); + smart_str_append_printf(str, "<%s> ", extension->URL); } - string_printf(str, "]\n"); + smart_str_appends(str, "]\n"); } /* }}} */ @@ -1689,15 +1613,14 @@ ZEND_METHOD(reflection_function, __toString) { reflection_object *intern; zend_function *fptr; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(fptr); - string_init(&str); _function_string(&str, fptr, intern->ce, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -2558,15 +2481,14 @@ ZEND_METHOD(reflection_parameter, __toString) { reflection_object *intern; parameter_reference *param; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(param); - string_init(&str); _parameter_string(&str, param->fptr, param->arg_info, param->offset, param->required, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -3160,15 +3082,14 @@ ZEND_METHOD(reflection_method, __toString) { reflection_object *intern; zend_function *mptr; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(mptr); - string_init(&str); _function_string(&str, mptr, intern->ce, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -3699,18 +3620,17 @@ ZEND_METHOD(reflection_class_constant, __toString) { reflection_object *intern; zend_class_constant *ref; - string str; + smart_str str = {0}; zval name; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ref); - string_init(&str); _default_get_entry(getThis(), "name", sizeof("name")-1, &name); _class_const_string(&str, Z_STRVAL(name), ref, ""); zval_ptr_dtor(&name); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -4050,15 +3970,14 @@ ZEND_METHOD(reflection_class, __toString) { reflection_object *intern; zend_class_entry *ce; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ce); - string_init(&str); _class_string(&str, ce, &intern->obj, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -5483,15 +5402,14 @@ ZEND_METHOD(reflection_property, __toString) { reflection_object *intern; property_reference *ref; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ref); - string_init(&str); _property_string(&str, &ref->prop, NULL, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -5819,15 +5737,14 @@ ZEND_METHOD(reflection_extension, __toString) { reflection_object *intern; zend_module_entry *module; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(module); - string_init(&str); _extension_string(&str, module, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ @@ -6182,15 +6099,14 @@ ZEND_METHOD(reflection_zend_extension, __toString) { reflection_object *intern; zend_extension *extension; - string str; + smart_str str = {0}; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(extension); - string_init(&str); _zend_extension_string(&str, extension, ""); - RETURN_NEW_STR(str.buf); + RETURN_STR(smart_str_extract(&str)); } /* }}} */ |