diff options
author | Zeev Suraski <zeev@php.net> | 2000-06-03 10:34:19 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 2000-06-03 10:34:19 +0000 |
commit | dae76aa1b5381b4fa2b3550742a0c44247166f2b (patch) | |
tree | 661e90b9018cfee2b0143444c5cb755b3192af3f /Zend/zend_operators.c | |
parent | 01d478ba56441d1b67b4064268ea7de6a5ca002b (diff) | |
download | php-git-dae76aa1b5381b4fa2b3550742a0c44247166f2b.tar.gz |
Support comparisons of arrays (with arrays) and objects (with objects)
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r-- | Zend/zend_operators.c | 99 |
1 files changed, 94 insertions, 5 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 57a72358f4..4ffe288887 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1042,6 +1042,7 @@ ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2) return SUCCESS; } + ZEND_API int compare_function(zval *result, zval *op1, zval *op2) { zval op1_copy, op2_copy; @@ -1075,15 +1076,53 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2) result->type = IS_LONG; return SUCCESS; } - if ((op1->type==IS_ARRAY || op1->type==IS_OBJECT) - && (op2->type==IS_ARRAY || op2->type==IS_OBJECT)) { - zend_error(E_WARNING,"Cannot compare arrays or objects"); + if (op1->type==IS_ARRAY && op2->type==IS_ARRAY) { + zend_compare_arrays(result, op1, op2); + return SUCCESS; + } + + if (op1->type==IS_OBJECT && op2->type==IS_OBJECT) { + zend_compare_objects(result, op1, op2); + return SUCCESS; + } + + if (op1->type==IS_ARRAY) { + result->value.lval = 1; + result->type = IS_LONG; + return SUCCESS; + } + if (op2->type==IS_ARRAY) { + result->value.lval = -1; + result->type = IS_LONG; + return SUCCESS; + } + if (op1->type==IS_OBJECT) { + result->value.lval = 1; + result->type = IS_LONG; + return SUCCESS; + } + if (op2->type==IS_OBJECT) { + result->value.lval = -1; + result->type = IS_LONG; + return SUCCESS; } + var_reset(result); return FAILURE; } +static int hash_zval_identical_function(const zval **z1, const zval **z2) +{ + zval result; + + if (is_identical_function(&result, (zval *) *z1, (zval *) *z2)==FAILURE) { + return 0; + } + return result.value.lval; +} + + ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2) { result->type = IS_BOOL; @@ -1116,8 +1155,22 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2) return SUCCESS; break; case IS_ARRAY: + if (zend_hash_compare(op1->value.ht, op2->value.ht, hash_zval_identical_function)==0) { + result->value.lval = 1; + } else { + result->value.lval = 0; + } + break; case IS_OBJECT: - zend_error(E_WARNING,"Cannot compare arrays or objects"); + if (op1->value.obj.ce != op2->value.obj.ce) { + result->value.lval = 0; + } else { + if (zend_hash_compare(op1->value.obj.properties, op2->value.obj.properties, hash_zval_identical_function)==0) { + result->value.lval = 1; + } else { + result->value.lval = 0; + } + } break; } var_reset(result); @@ -1128,7 +1181,7 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2) ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2) { result->type = IS_BOOL; - if ( is_identical_function( result, op1, op2 ) == FAILURE ) { + if (is_identical_function( result, op1, op2 ) == FAILURE) { return FAILURE; } result->value.lval = !result->value.lval; @@ -1478,6 +1531,42 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) } +static int hash_zval_compare_function(const zval **z1, const zval **z2) +{ + zval result; + + if (compare_function(&result, (zval *) *z1, (zval *) *z2)==FAILURE) { + return 0; + } + return result.value.lval; +} + + + +ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2) +{ + result->type = IS_LONG; + result->value.lval = zend_hash_compare(ht1, ht2, hash_zval_compare_function); +} + + +ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2) +{ + zend_compare_symbol_tables(result, a1->value.ht, a2->value.ht); +} + + +ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2) +{ + if (o1->value.obj.ce != o2->value.obj.ce) { + result->value.lval = 1; /* Comparing objects of different types is pretty much meaningless */ + result->type = IS_LONG; + return; + } + zend_compare_symbol_tables(result, o1->value.obj.properties, o2->value.obj.properties); +} + + /* returns 0 for non-numeric string * returns IS_DOUBLE for floating point string, and assigns the value to *dval (if it's not NULL) * returns IS_LONG for integer strings, and assigns the value to *lval (if it's not NULL) |