]> granicus.if.org Git - php/commitdiff
- Support unordered hash comparisons
authorZeev Suraski <zeev@php.net>
Sun, 4 Jun 2000 21:59:49 +0000 (21:59 +0000)
committerZeev Suraski <zeev@php.net>
Sun, 4 Jun 2000 21:59:49 +0000 (21:59 +0000)
- Make == perform an unordered comparison with arrays/objects, and === perform an ordered comparison

Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_operators.c

index af532da0a4cc8817aa111af111cd854a3e822e43..6eebc8de28ba0145fe2f291761bc0eb9dae8e974 100644 (file)
@@ -1068,10 +1068,11 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func,
 }
 
 
-ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar)
+ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered)
 {
        Bucket *p1, *p2;
        int result;
+       void *pData2;
 
        IS_CONSISTENT(ht1);
        IS_CONSISTENT(ht2);
@@ -1080,31 +1081,52 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
        if (result!=0) {
                return result;
        }
+
        p1 = ht1->pListHead;
-       p2 = ht2->pListHead;
+       if (ordered) {
+               p2 = ht2->pListHead;
+       }
 
-       while (p1 && p2) {
-               if (p1->nKeyLength==0 && p2->nKeyLength==0) { /* numeric indices */
-                       result = p1->h - p2->h;
-                       if (result!=0) {
-                               return result;
-                       }
-               } else { /* string indices */
-                       result = p1->nKeyLength - p2->nKeyLength;
-                       if (result!=0) {
-                               return result;
+       while (p1) {
+               if (ordered && !p2) {
+                       return 1; /* That's not supposed to happen */
+               }
+               if (ordered) {
+                       if (p1->nKeyLength==0 && p2->nKeyLength==0) { /* numeric indices */
+                               result = p1->h - p2->h;
+                               if (result!=0) {
+                                       return result;
+                               }
+                       } else { /* string indices */
+                               result = p1->nKeyLength - p2->nKeyLength;
+                               if (result!=0) {
+                                       return result;
+                               }
+                               result = memcmp(p1->arKey, p2->arKey, p1->nKeyLength);
+                               if (result!=0) {
+                                       return result;
+                               }
                        }
-                       result = memcmp(p1->arKey, p2->arKey, p1->nKeyLength);
-                       if (result!=0) {
-                               return result;
+                       pData2 = p2->pData;
+               } else {
+                       if (p1->nKeyLength==0) { /* numeric index */
+                               if (zend_hash_index_find(ht2, p1->h, &pData2)==FAILURE) {
+                                       return 1;
+                               }
+                       } else { /* string index */
+                               if (zend_hash_find(ht2, p1->arKey, p1->nKeyLength, &pData2)==FAILURE) {
+                                       return 1;
+                               }
                        }
                }
-               result = compar(p1->pData, p2->pData);
+               result = compar(p1->pData, pData2);
                if (result!=0) {
                        return result;
                }
                p1 = p1->pListNext;
-               p2 = p2->pListNext;
+               if (ordered) {
+                       p2 = p2->pListNext;
+               }
        }
 
        return 0;
index 88741ae71352467ca2f69431be0206415620b79e..13f03c43576c4114c762c4e65fd6155e3e423790 100644 (file)
@@ -166,7 +166,7 @@ ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos
 ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size);
 ZEND_API void zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, void *tmp, uint size, int overwrite);
 ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, int renumber);
-ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar);
+ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered);
 ZEND_API int zend_hash_minmax(HashTable *ht, int (*compar)(const void *, const void *), int flag, void **pData);
 
 ZEND_API int zend_hash_num_elements(HashTable *ht);
index 4ffe2888870a306158856460418a0bda9bfe3ce8..e9f9e91e8f928c99927e1e2de4f19fb1028378d3 100644 (file)
@@ -1116,10 +1116,15 @@ static int hash_zval_identical_function(const zval **z1, const zval **z2)
 {
        zval result;
 
+       /* is_identical_function() returns 1 in case of identity and 0 in case
+        * of a difference;
+        * whereas this comparison function is expected to return 0 on identity,
+        * and non zero otherwise.
+        */
        if (is_identical_function(&result, (zval *) *z1, (zval *) *z2)==FAILURE) {
-               return 0;
+               return 1;
        }
-       return result.value.lval;
+       return !result.value.lval;
 }
 
 
@@ -1133,17 +1138,14 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2)
        switch (op1->type) {
                case IS_NULL:
                        result->value.lval = (op2->type==IS_NULL);
-                       return SUCCESS;
                        break;
                case IS_BOOL:
                case IS_LONG:
                case IS_RESOURCE:
                        result->value.lval = (op1->value.lval == op2->value.lval);
-                       return SUCCESS;
                        break;
                case IS_DOUBLE:
                        result->value.lval = (op1->value.dval == op2->value.dval);
-                       return SUCCESS;
                        break;
                case IS_STRING:
                        if ((op1->value.str.len == op2->value.str.len)
@@ -1152,10 +1154,9 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2)
                        } else {
                                result->value.lval = 0;
                        }
-                       return SUCCESS;
                        break;
                case IS_ARRAY:
-                       if (zend_hash_compare(op1->value.ht, op2->value.ht, hash_zval_identical_function)==0) {
+                       if (zend_hash_compare(op1->value.ht, op2->value.ht, hash_zval_identical_function, 1)==0) {
                                result->value.lval = 1;
                        } else {
                                result->value.lval = 0;
@@ -1165,16 +1166,18 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2)
                        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) {
+                               if (zend_hash_compare(op1->value.obj.properties, op2->value.obj.properties, hash_zval_identical_function, 1)==0) {
                                        result->value.lval = 1;
                                } else {
                                        result->value.lval = 0;
                                }
                        }
                        break;
+               default:
+                       var_reset(result);
+                       return FAILURE;
        }
-       var_reset(result);
-       return FAILURE;
+       return SUCCESS;
 }
 
 
@@ -1536,7 +1539,7 @@ 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 1;
        }
        return result.value.lval;
 }
@@ -1546,7 +1549,7 @@ static int hash_zval_compare_function(const zval **z1, const zval **z2)
 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);
+       result->value.lval = zend_hash_compare(ht1, ht2, hash_zval_compare_function, 0);
 }