Browse Source

* 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".
experimental/newoperator
Zeev Suraski 27 years ago
parent
commit
da9faa2c3a
  1. 79
      Zend/zend.c
  2. 1
      Zend/zend.h
  3. 11
      Zend/zend_execute.c
  4. 2
      Zend/zend_execute_API.c

79
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;

1
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);

11
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:

2
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;
}

Loading…
Cancel
Save