summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>1999-06-11 10:44:26 +0000
committerZeev Suraski <zeev@php.net>1999-06-11 10:44:26 +0000
commitda9faa2c3a7db0f222e751e899c843a1f6561e8b (patch)
treeeb7a22ce11a5935885bee80bc0d7bf418ac7d529 /Zend
parent1798a0183a962342948bd9110435994d87853a8b (diff)
downloadphp-git-da9faa2c3a7db0f222e751e899c843a1f6561e8b.tar.gz
* Make the output handling of variables much, much cooler.
Uses zend_make_printable_zval() instead of convert_to_string() now: $foo = true; print "\$foo is $foo"; will now print $foo is true (instead of "$foo is 1", earlier). Also, with objects, it automatically tries to call __print() and use it as a printing function. For example: class foo { function __print() { return "Foo Object"; } }; $foo = new foo; print $foo; will print "Foo Object".
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend.c79
-rw-r--r--Zend/zend.h1
-rw-r--r--Zend/zend_execute.c11
-rw-r--r--Zend/zend_execute_API.c2
4 files changed, 62 insertions, 31 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index ef9a39451b..fdc6be4a3f 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -22,6 +22,7 @@
#include "modules.h"
#include "zend_constants.h"
#include "zend_list.h"
+#include "zend_API.h"
#ifdef ZTS
# define GLOBAL_FUNCTION_TABLE global_function_table
@@ -97,38 +98,72 @@ static void print_hash(HashTable *ht, int indent)
}
-ZEND_API int zend_print_zval(zval *expr, int indent)
+ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy)
{
- zval expr_copy;
- int destroy=0;
-
- if (expr->type != IS_STRING) {
- if (expr->type == IS_BOOL) {
+ if (expr->type==IS_STRING) {
+ *use_copy = 0;
+ return;
+ }
+ switch (expr->type) {
+ case IS_BOOL:
if (expr->value.lval) {
- expr_copy.value.str.val = estrndup("true",4);
- expr_copy.value.str.len = 4;
+ expr_copy->value.str.len = sizeof("true")-1;
+ expr_copy->value.str.val = estrndup("true", expr_copy->value.str.len);
} else {
- expr_copy.value.str.val = estrndup("false",5);
- expr_copy.value.str.len = 5;
+ expr_copy->value.str.len = sizeof("false")-1;
+ expr_copy->value.str.val = estrndup("false", expr_copy->value.str.len);
}
- expr_copy.type = IS_STRING;
- } else if (expr->type == IS_RESOURCE) {
- expr_copy.value.str.val = (char *) emalloc(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG);
- expr_copy.value.str.len = sprintf(expr_copy.value.str.val, "Resource id #%ld", expr->value.lval);
- expr_copy.type = IS_STRING;
- } else {
- expr_copy = *expr;
- zval_copy_ctor(&expr_copy);
- convert_to_string(&expr_copy);
- }
+ break;
+ case IS_RESOURCE:
+ expr_copy->value.str.val = (char *) emalloc(sizeof("Resource id #")-1 + MAX_LENGTH_OF_LONG);
+ expr_copy->value.str.len = sprintf(expr_copy->value.str.val, "Resource id #%ld", expr->value.lval);
+ break;
+ case IS_ARRAY:
+ expr_copy->value.str.len = sizeof("Array")-1;
+ expr_copy->value.str.val = estrndup("Array", expr_copy->value.str.len);
+ break;
+ case IS_OBJECT: {
+ zval function_name;
+
+ function_name.value.str.len = sizeof("__print")-1;
+ function_name.value.str.val = estrndup("__print", function_name.value.str.len);
+ function_name.type = IS_STRING;
+
+ if (call_user_function(NULL, expr, &function_name, expr_copy, 0, NULL)==FAILURE) {
+ expr_copy->value.str.len = sizeof("Object")-1;
+ expr_copy->value.str.val = estrndup("Object", expr_copy->value.str.len);
+ }
+ efree(function_name.value.str.val);
+ }
+ break;
+ default:
+ *expr_copy = *expr;
+ zval_copy_ctor(expr_copy);
+ convert_to_string(expr_copy);
+ break;
+ }
+ expr_copy->type = IS_STRING;
+ *use_copy = 1;
+}
+
+
+ZEND_API int zend_print_zval(zval *expr, int indent)
+{
+ zval expr_copy;
+ int use_copy;
+
+ zend_make_printable_zval(expr, &expr_copy, &use_copy);
+ if (use_copy) {
expr = &expr_copy;
- destroy=1;
}
if (expr->value.str.len==0) { /* optimize away empty strings */
+ if (use_copy) {
+ zval_dtor(expr);
+ }
return 0;
}
ZEND_WRITE(expr->value.str.val,expr->value.str.len);
- if (destroy) {
+ if (use_copy) {
zval_dtor(expr);
}
return expr->value.str.len;
diff --git a/Zend/zend.h b/Zend/zend.h
index ece884f84a..56fd918bcf 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -180,6 +180,7 @@ ZEND_API void zend_bailout();
END_EXTERN_C()
ZEND_API char *get_zend_version();
+ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
ZEND_API int zend_print_zval(zval *expr, int indent);
ZEND_API void zend_print_zval_r(zval *expr, int indent);
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index b18a8ef27d..e6e7ac3d8e 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1217,19 +1217,16 @@ binary_assign_op_addr: {
case ZEND_ADD_VAR: {
zval *var = get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R);
zval var_copy;
- int destroy=0;
+ int use_copy;
- if (var->type != IS_STRING) {
- var_copy = *var;
- zval_copy_ctor(&var_copy);
+ zend_make_printable_zval(var, &var_copy, &use_copy);
+ if (use_copy) {
var = &var_copy;
- convert_to_string(var);
- destroy=1;
}
add_string_to_string( &Ts[opline->result.u.var].tmp_var,
get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_NA),
var);
- if (destroy) {
+ if (use_copy) {
zval_dtor(var);
}
/* original comment, possibly problematic:
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 5440103d7d..bce067597d 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -276,12 +276,10 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n
return FAILURE;
}
function_table = &object->value.obj.ce->function_table;
- /* unimplemented */
}
original_function_state_ptr = EG(function_state_ptr);
zend_str_tolower(function_name->value.str.val, function_name->value.str.len);
if (zend_hash_find(function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function_state.function)==FAILURE) {
- zend_error(E_ERROR, "Unknown function: %s()\n", function_name->value.str.val);
return FAILURE;
}