HashTable *properties = NULL;
char *class_name = NULL;
zend_uint clen;
-
+
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
}
break;
case IS_OBJECT:
{
- HashTable *properties = NULL;
+ HashTable *properties;
char *class_name = NULL;
zend_uint clen;
-
+ int is_temp;
+
if (Z_OBJ_HANDLER_P(expr, get_class_name)) {
Z_OBJ_HANDLER_P(expr, get_class_name)(expr, &class_name, &clen, 0 TSRMLS_CC);
}
if (class_name) {
efree(class_name);
}
- if (Z_OBJ_HANDLER_P(expr, get_properties)) {
- properties = Z_OBJPROP_P(expr);
+ if ((properties = Z_OBJDEBUG_P(expr, is_temp)) == NULL) {
+ break;
}
- if (properties) {
- if (++properties->nApplyCount>1) {
- ZEND_PUTS_EX(" *RECURSION*");
- properties->nApplyCount--;
- return;
- }
- print_hash(write_func, properties, indent, 1 TSRMLS_CC);
+ if (++properties->nApplyCount>1) {
+ ZEND_PUTS_EX(" *RECURSION*");
properties->nApplyCount--;
+ return;
+ }
+ print_hash(write_func, properties, indent, 1 TSRMLS_CC);
+ properties->nApplyCount--;
+ if (is_temp) {
+ zend_hash_destroy(properties);
+ efree(properties);
}
break;
}
short_tags_default = CG(short_tags);
ct_pass_ref_default = CG(allow_call_time_pass_reference);
extended_info_default = CG(extended_info);
-
+
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
free(compiler_globals->function_table);
free(compiler_globals->class_table);
} zend_end_try();
}
-void zend_call_destructors(TSRMLS_D)
+void zend_call_destructors(TSRMLS_D)
{
zend_try {
shutdown_destructors(TSRMLS_C);
orig_user_error_handler = EG(user_error_handler);
EG(user_error_handler) = NULL;
-
+
/* User error handler may include() additinal PHP files.
* If an error was generated during comilation PHP will compile
- * such scripts recursivly, but some CG() variables may be
- * inconsistent. */
+ * such scripts recursivly, but some CG() variables may be
+ * inconsistent. */
in_compilation = zend_is_compiling(TSRMLS_C);
if (in_compilation) {
if (!EG(user_error_handler)) {
EG(user_error_handler) = orig_user_error_handler;
- }
+ }
else {
zval_ptr_dtor(&orig_user_error_handler);
}
set, we call __set handler. If it fails, we do not change the array.
for both handlers above, when we are inside __get/__set, no further calls for
- __get/__set for this property of this object will be made, to prevent endless
+ __get/__set for this property of this object will be made, to prevent endless
recursion and enable accessors to change properties array.
if we have __call and method which is not part of the class function table is
called, we cal __call handler.
*/
-static HashTable *zend_std_get_properties(zval *object TSRMLS_DC)
+ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC)
{
zend_object *zobj;
zobj = Z_OBJ_P(object);
#if DEBUG_OBJECT_HANDLERS
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member));
-#endif
+#endif
/* make zend_get_property_info silent if we have getter - we may want to use it */
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC);
zend_function *fbc;
char *lc_method_name;
zval *object = *object_ptr;
-
+
lc_method_name = do_alloca(method_len+1);
/* Create a zend_copy_str_tolower(dest, src, src_length); */
zend_str_tolower_copy(lc_method_name, method_name, method_len);
-
+
zobj = Z_OBJ_P(object);
if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) {
free_alloca(lc_method_name);
zval *method_name_ptr, *method_args_ptr;
zval *method_result_ptr = NULL;
zend_class_entry *ce = EG(scope);
-
+
ALLOC_ZVAL(method_args_ptr);
INIT_PZVAL(method_args_ptr);
array_init(method_args_ptr);
callstatic_user_call->arg_info = NULL;
callstatic_user_call->num_args = 0;
callstatic_user_call->scope = ce;
- callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC;
+ callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC;
callstatic_user_call->function_name = estrndup(function_name_strval, function_name_strlen);
callstatic_user_call->pass_rest_by_reference = 0;
callstatic_user_call->return_reference = ZEND_RETURN_VALUE;
zend_std_compare_objects, /* compare_objects */
zend_std_cast_object_tostring, /* cast_object */
NULL, /* count_elements */
+ NULL, /* get_debug_info */
};
/*
/* Used to get hash of the properties of the object, as hash of zval's */
typedef HashTable *(*zend_object_get_properties_t)(zval *object TSRMLS_DC);
+typedef HashTable *(*zend_object_get_debug_info_t)(zval *object, int *is_temp TSRMLS_DC);
+
/* Used to call methods */
/* args on stack! */
/* Andi - EX(fbc) (function being called) needs to be initialized already in the INIT fcall opcode so that the parameters can be parsed the right way. We need to add another callback for this.
zend_object_compare_t compare_objects;
zend_object_cast_t cast_object;
zend_object_count_elements_t count_elements;
+ zend_object_get_debug_info_t get_debug_info;
};
extern ZEND_API zend_object_handlers std_object_handlers;
ZEND_API union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC);
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC);
+ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC);
+ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC);
ZEND_API int zend_std_cast_object_tostring(zval *readobj, zval *writeobj, int type TSRMLS_DC);
#define Z_OBJPROP(zval) Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
#define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
#define Z_RESVAL(zval) (zval).value.lval
+#define Z_OBJDEBUG(zval,is_tmp) (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&is_tmp TSRMLS_CC):(is_tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
#define Z_LVAL_P(zval_p) Z_LVAL(*zval_p)
#define Z_BVAL_P(zval_p) Z_BVAL(*zval_p)
#define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p)
#define Z_OBJ_HT_P(zval_p) Z_OBJ_HT(*zval_p)
#define Z_OBJ_HANDLER_P(zval_p, h) Z_OBJ_HANDLER(*zval_p, h)
+#define Z_OBJDEBUG_P(zval_p,is_tmp) Z_OBJDEBUG(*zval_p,is_tmp)
#define Z_LVAL_PP(zval_pp) Z_LVAL(**zval_pp)
#define Z_BVAL_PP(zval_pp) Z_BVAL(**zval_pp)
#define Z_OBJ_HANDLE_PP(zval_p) Z_OBJ_HANDLE(**zval_p)
#define Z_OBJ_HT_PP(zval_p) Z_OBJ_HT(**zval_p)
#define Z_OBJ_HANDLER_PP(zval_p, h) Z_OBJ_HANDLER(**zval_p, h)
+#define Z_OBJDEBUG_PP(zval_pp,is_tmp) Z_OBJDEBUG(**zval_pp,is_tmp)
#define Z_TYPE(zval) (zval).type
#define Z_TYPE_P(zval_p) Z_TYPE(*zval_p)
static xmlNodePtr sxe_get_element_by_offset(php_sxe_object *sxe, long offset, xmlNodePtr node, long *cnt) /* {{{ */
{
long nodendx = 0;
-
+
if (sxe->iter.type == SXE_ITER_NONE) {
if (offset == 0) {
if (cnt) {
next_iter:
node = node->next;
}
-
+
if (cnt) {
*cnt = nodendx;
}
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
- elements = 0;
+ elements = 0;
node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
}
} else if (member) {
node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, &cnt);
- } else {
+ } else {
node = NULL;
}
if (node) {
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
- elements = 0;
+ elements = 0;
node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
if (!node) {
if (!member || Z_TYPE_P(member) == IS_LONG) {
newnode = xmlNewTextChild(mynode->parent, mynode->ns, mynode->name, value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
- } else {
+ } else {
newnode = xmlNewTextChild(mynode, mynode->ns, (xmlChar *)Z_STRVAL_P(member), value ? (xmlChar *)Z_STRVAL_P(value) : NULL);
}
} else if (!member || Z_TYPE_P(member) == IS_LONG) {
_node_as_zval(sxe, node, return_value, type, name, sxe->iter.nsprefix, sxe->iter.isprefix TSRMLS_CC);
sxe = php_sxe_fetch_object(return_value TSRMLS_CC);
+ if (sxe->tmp) {
+ zval_ptr_dtor(&sxe->tmp);
+ }
sxe->tmp = return_value;
Z_SET_ISREF_P(return_value);
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
- elements = 0;
+ elements = 0;
node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
}
if (node) {
exists = 1;
- if (check_empty == 1 &&
+ if (check_empty == 1 &&
(!node->children || (node->children->type == XML_TEXT_NODE && !node->children->next &&
(!node->children->content || !node->children->content[0] || !xmlStrcmp(node->children->content, "0")))) ) {
exists = 0;
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
- elements = 0;
+ elements = 0;
node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
char *res = estrdup((char*)tmp);
xmlFree(tmp);
-
+
return res;
}
}
}
-/* {{{ sxe_properties_get()
+/* {{{ sxe_get_prop_hash()
*/
-static HashTable * sxe_properties_get(zval *object TSRMLS_DC)
+static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{{ */
{
zval *value;
zval *zattr;
sxe = php_sxe_fetch_object(object TSRMLS_CC);
- if (sxe->properties) {
+ if (is_debug) {
+ ALLOC_HASHTABLE(rv);
+ zend_hash_init(rv, 0, NULL, ZVAL_PTR_DTOR, 0);
+ }
+ else if (sxe->properties) {
zend_hash_clean(sxe->properties);
rv = sxe->properties;
} else {
if (!node) {
return rv;
}
- if (1||sxe->iter.type != SXE_ITER_CHILD) {
+ if (is_debug) {
if (sxe->iter.type == SXE_ITER_ELEMENT) {
node = php_sxe_get_first_node(sxe, node TSRMLS_CC);
}
}
/* }}} */
+static HashTable * sxe_get_properties(zval *object TSRMLS_DC) /* {{{ */
+{
+ return sxe_get_prop_hash(object, 0 TSRMLS_CC);
+}
+/* }}} */
+
+static HashTable * sxe_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */
+{
+ *is_temp = 1;
+ return sxe_get_prop_hash(object, 1 TSRMLS_CC);
+}
+/* }}} */
+
static int sxe_objects_compare(zval *object1, zval *object2 TSRMLS_DC) /* {{{ */
{
php_sxe_object *sxe1;
{
xmlAttrPtr attr;
- if (node->ns) {
+ if (node->ns) {
sxe_add_namespace_name(return_value, node->ns);
}
attr = node->properties;
while (attr) {
- if (attr->ns) {
+ if (attr->ns) {
sxe_add_namespace_name(return_value, attr->ns);
}
attr = attr->next;
sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
GET_NODE(sxe, node);
-
+
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
return; /* attributes don't have attributes */
}
if (node == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree");
- return;
+ return;
}
localname = xmlSplitQName2((xmlChar *)qname, &prefix);
xmlChar *contents = NULL;
xmlNodePtr node;
int rv;
+ HashTable *prop_hash;
sxe = php_sxe_fetch_object(readobj TSRMLS_CC);
-
+
if (type == IS_BOOL) {
node = php_sxe_get_first_node(sxe, NULL TSRMLS_CC);
+ prop_hash = sxe_get_prop_hash(readobj, 1 TSRMLS_CC);
INIT_PZVAL(writeobj);
- ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(sxe_properties_get(readobj TSRMLS_CC)) > 0);
+ ZVAL_BOOL(writeobj, node != NULL || zend_hash_num_elements(prop_hash) > 0);
+ zend_hash_destroy(prop_hash);
+ efree(prop_hash);
return SUCCESS;
}
sxe->iter.data = NULL;
node = php_sxe_reset_iterator(sxe, 0 TSRMLS_CC);
-
+
while (node)
{
(*count)++;
sxe_property_delete,
sxe_dimension_exists,
sxe_dimension_delete,
- sxe_properties_get,
+ sxe_get_properties,
NULL, /* zend_get_std_object_handlers()->get_method,*/
NULL, /* zend_get_std_object_handlers()->call_method,*/
NULL, /* zend_get_std_object_handlers()->get_constructor, */
NULL, /* zend_get_std_object_handlers()->get_class_name,*/
sxe_objects_compare,
sxe_object_cast,
- sxe_count_elements
+ sxe_count_elements,
+ sxe_get_debug_info
};
static zend_object_handlers sxe_ze1_object_handlers = {
sxe_property_delete,
sxe_dimension_exists,
sxe_dimension_delete,
- sxe_properties_get,
+ sxe_get_properties,
NULL, /* zend_get_std_object_handlers()->get_method,*/
NULL, /* zend_get_std_object_handlers()->call_method,*/
NULL, /* zend_get_std_object_handlers()->get_constructor, */
NULL, /* zend_get_std_object_handlers()->get_class_name,*/
sxe_objects_compare,
sxe_object_cast,
- sxe_count_elements
+ sxe_count_elements,
+ sxe_get_debug_info
};
static zend_object_value sxe_object_ze1_clone(zval *zobject TSRMLS_DC)
sxe = php_sxe_fetch_object(object TSRMLS_CC);
GET_NODE(sxe, node);
- return php_sxe_get_first_node(sxe, node TSRMLS_CC);
+ return php_sxe_get_first_node(sxe, node TSRMLS_CC);
}
/* {{{ proto simplemxml_element simplexml_import_dom(domNode node [, string class_name])
char *class_name;
zend_uint class_name_len;
int (*php_element_dump_func)(zval**, int, va_list, zend_hash_key*);
+ int is_temp;
if (level > 1) {
php_printf("%*c", level - 1, ' ');
}
php_printf("%sarray(%d) {\n", COMMON, zend_hash_num_elements(myht));
php_element_dump_func = php_array_element_dump;
+ is_temp = 0;
goto head_done;
case IS_OBJECT:
- myht = Z_OBJPROP_PP(struc);
+ myht = Z_OBJDEBUG_PP(struc, is_temp);
if (myht && myht->nApplyCount > 1) {
PUTS("*RECURSION*\n");
return;
head_done:
if (myht) {
zend_hash_apply_with_arguments(myht, (apply_func_args_t) php_element_dump_func, 1, level);
+ if (is_temp) {
+ zend_hash_destroy(myht);
+ efree(myht);
+ }
}
if (level > 1) {
php_printf("%*c", level-1, ' ');