static void Word_mergeRunsRecursive(DFNode *node) { DFNode *current = node->first; while (current != NULL) { DFNode *next = current->next; if ((current->tag == WORD_R) && (next != NULL) && (next->tag == WORD_R)) { DFNode *currentRPr = DFChildWithTag(current,WORD_RPR); DFNode *nextRPr = DFChildWithTag(next,WORD_RPR); if (nodesEqual(currentRPr,nextRPr)) { while (next->first != NULL) { if (next->first->tag == WORD_RPR) DFRemoveNode(next->first); else DFAppendChild(current,next->first); } DFRemoveNode(next); continue; } } current = next; } for (current = node->first; current != NULL; current = current->next) Word_mergeRunsRecursive(current); }
// Returns 0 or the index of the name of the expression. u32 indexHelper( const LNZprogram* p, u32 expr, const LNZprogram* names ){ u32 ind = 0; if( names == NULL ) return getIndex( p->pointers, (const u8*)( &expr ), sizeof( u32 ) ); else{ for( int i = names->pointers->size - 1; i >= 0; --i ) if( nodesEqual( p, expr, names, *( (const u32*)( names->pointers->revdict[ i ] ) ) ) ){ ind = i + 1; break; } } return ind; }
bool Node::contains(const Node& potentialChild, bool simpleSelectorOrderDependent) const { bool found = false; for (NodeDeque::iterator iter = mpCollection->begin(), iterEnd = mpCollection->end(); iter != iterEnd; iter++) { Node& toTest = *iter; if (nodesEqual(toTest, potentialChild, simpleSelectorOrderDependent)) { found = true; break; } } return found; }
static int nodesEqual(DFNode *a, DFNode *b) { if ((a == NULL) && (b == NULL)) return 1; if ((a == NULL) || (b == NULL)) return 0; if (a->tag != b->tag) return 0; if (a->tag < MIN_ELEMENT_TAG) return 0; // First check if the number and type of children are the same DFNode *aChild = a->first; DFNode *bChild = b->first; while ((aChild != NULL) || (bChild != NULL)) { if ((aChild != NULL) && (bChild == NULL)) return 0; if ((aChild == NULL) && (bChild != NULL)) return 0; if (aChild->tag != bChild->tag) return 0; aChild = aChild->next; bChild = bChild->next; } // Next check the attributes if (!attributesEqual(a,b)) return 0; // Now check the *content* of the children. We do this after the above as it is more expensive. aChild = a->first; bChild = b->first; while ((aChild != NULL) || (bChild != NULL)) { if (!nodesEqual(aChild,bChild)) return 0; aChild = aChild->next; bChild = bChild->next; } return 1; }
bool nodesEqual(const Node& lhs, const Node& rhs, bool simpleSelectorOrderDependent) { if (lhs.type() != rhs.type()) { return false; } if (lhs.isCombinator()) { return lhs.combinator() == rhs.combinator(); } else if (lhs.isNil()) { return true; // no state to check } else if (lhs.isSelector()){ return selectors_equal(*lhs.selector(), *rhs.selector(), simpleSelectorOrderDependent); } else if (lhs.isCollection()) { if (lhs.collection()->size() != rhs.collection()->size()) { return false; } for (NodeDeque::iterator lhsIter = lhs.collection()->begin(), lhsIterEnd = lhs.collection()->end(), rhsIter = rhs.collection()->begin(); lhsIter != lhsIterEnd; lhsIter++, rhsIter++) { if (!nodesEqual(*lhsIter, *rhsIter, simpleSelectorOrderDependent)) { return false; } } return true; } // We shouldn't get here. throw "Comparing unknown node types. A new type was probably added and this method wasn't implemented for it."; }
bool Node::operator==(const Node& rhs) const { return nodesEqual(*this, rhs, true /*simpleSelectorOrderDependent*/); }