diff -r 000000000000 -r f58d6ec98e88 cdlcompilertoolkit/src/CdlTkInterfaceCheck.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cdlcompilertoolkit/src/CdlTkInterfaceCheck.cpp Thu Dec 17 09:14:18 2009 +0200 @@ -0,0 +1,162 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ +#include "CdlCompilerToolkit/CdlTkProcess.h" +#include +using namespace std; + +namespace CdlCompilerToolkit { + +// +// CCdlTkApiListComparator +// + +class CCdlTkApiListComparator + { +public: + CCdlTkApiListComparator(CCdlTkApiList::const_iterator& aIter) : iIter(aIter) {} + bool operator()(const CCdlTkApi* aApi) { return *aApi == **iIter; } + CCdlTkApiList::const_iterator& iIter; + }; + + +// +// CCdlTkApiChecker +// + +CCdlTkApiChecker::CCdlTkApiChecker(const CCdlTkInterface& aLeft, + const CCdlTkInterface& aRight, + MCdlTkApiCheckObserver& aObserver) +: iLeft(aLeft), iRight(aRight), iObserver(aObserver) + { + } + +CCdlTkApiChecker::~CCdlTkApiChecker() + { + } + +void CCdlTkApiChecker::Process() + { + iObserver.StartCheck(); + + const CCdlTkApiList& leftList = iLeft.ApiList(); + const CCdlTkApiList& rightList = iRight.ApiList(); + + CApiListIter posLeft = leftList.begin(); + CApiListIter posRight = rightList.begin(); + CApiListIter leftEnd = leftList.end(); + CApiListIter rightEnd = rightList.end(); + + while (posLeft!=leftEnd && posRight!=rightEnd) + { + // if left and right APIs don't match, + // move the iterators till they do, or they hit the end + if (**posLeft != **posRight) + ReSync(posLeft, posRight, leftEnd, rightEnd); + + if (posLeft == leftEnd || posRight == rightEnd) + { + // if either iterator hits the end, fail everything remaining + FailLeft(posLeft, leftEnd); + FailRight(posRight, rightEnd); + } + else + { + // the APIs match, so tell the observer and move on + iObserver.ApiInBoth(**posLeft); + ++posLeft; + ++posRight; + } + } + + iObserver.CheckComplete(); + } + +// This function moves the iterators posLeft and posRight onwards till they +// match APIs again, or they hit the ends. +void CCdlTkApiChecker::ReSync(CApiListIter& posLeft, CApiListIter& posRight, + const CApiListIter& leftEnd, const CApiListIter& rightEnd) const + { + // lookaheadLeft and lookaheadRight are how far we are looking ahead for a match + CApiListIter lookaheadLeft = posLeft; + CApiListIter lookaheadRight = posRight; + + // predicates for finding an API in a range + CCdlTkApiListComparator chkContainsLeft(lookaheadLeft); + CCdlTkApiListComparator chkContainsRight(lookaheadRight); + + // keep going till we get a match or reach the end + for (;;) + { + // move lookahead iterators on one step + ++lookaheadLeft; + ++lookaheadRight; + + // stop and fail if we've hit the end on the left + if (lookaheadLeft == leftEnd) + { + FailLeft(posLeft, leftEnd); + break; + } + + // stop and fail if we've hit the end on the right + if (lookaheadRight == rightEnd) + { + FailRight(posRight, rightEnd); + break; + } + + // look through LHS lookahead range for the RHS API at the lookahead position + CApiListIter foundLeft = find_if(posLeft, lookaheadLeft+1, chkContainsRight); + if (foundLeft != lookaheadLeft+1) + { + // found a match, fail everything up till the match position and stop + FailLeft(posLeft, foundLeft); + FailRight(posRight, lookaheadRight); + break; + } + + // look through RHS lookahead range for the LHS API at the lookahead position + CApiListIter foundRight = find_if(posRight, lookaheadRight+1, chkContainsLeft); + if (foundRight != lookaheadRight+1) + { + // found a match, fail everything up till the match position and stop + FailLeft(posLeft, lookaheadLeft); + FailRight(posRight, foundRight); + break; + } + } + } + +void CCdlTkApiChecker::FailLeft(CApiListIter& aFrom, const CApiListIter& aTo) const + { + while (aFrom != aTo) + { + iObserver.ApiNotInRight(**aFrom); + ++aFrom; + } + } + +void CCdlTkApiChecker::FailRight(CApiListIter& aFrom, const CApiListIter& aTo) const + { + while (aFrom != aTo) + { + iObserver.ApiNotInLeft(**aFrom); + ++aFrom; + } + } + +} // end of namespace CdlCompilerToolkit