static int oostruct_compare(at *p, at *q, int order) { if (order) error(NIL, "cannot rank objects", NIL); object_t *obj1 = Mptr(p); object_t *obj2 = Mptr(q); class_t *cl1 = Class(obj1->backptr); class_t *cl2 = Class(obj2->backptr); if (cl1->num_slots != cl2->num_slots) return 1; /* check that slots names match before comparing values */ for (int i=0; i<cl1->num_slots; i++) if (cl1->slots[i] != cl2->slots[i]) return 1; for(int i=0; i<cl1->num_slots; i++) { if (!eq_test(obj1->slots[i], obj2->slots[i])) return 1; } return 0; }
int eq_test(at *p, at *q) { int ans = TRUE; at *pslow = p; struct recur_elt elt; char toggle = 0; again: /* Trivial */ if (p == q) return TRUE; else if (!p || !q) return FALSE; /* List */ else if ((p->flags & C_CONS) && (q->flags & C_CONS)) { if (recur_push_ok(&elt, &eq_test, p)) { ans = eq_test(p->Car, q->Car); recur_pop(&elt); } if (ans) { /* go to next list element */ p = p->Cdr; q = q->Cdr; if (p==pslow) /* circular list detected */ return ans; toggle ^= 1; if (toggle) pslow = pslow->Cdr; goto again; } return ans; } /* Number */ else if ((p->flags & C_NUMBER) && (q->flags & C_NUMBER)) { #if defined(WIN32) && defined(_MSC_VER) && defined(_M_IX86) if (p->Number == q->Number) { float delta = (float)(p->Number - q->Number); if (! *(long*)&delta) return TRUE; } #else if (p->Number == q->Number) return TRUE; #endif return FALSE; } /* Comparison method provided */ else if ((p->flags & C_EXTERN) && (q->flags & C_EXTERN) && (p->Class == q->Class) && (p->Class->compare) ) { if (recur_push_ok(&elt, &eq_test, p)) { ans = !(*p->Class->compare)(p,q,FALSE); recur_pop(&elt); } return ans; } /* GPTR */ else if ((p->flags & C_GPTR) && (q->flags & C_GPTR) ) { if (p->Gptr == q->Gptr) return TRUE; return FALSE; } /* No way to prove that objects are equal */ return FALSE; }