|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include "CdlCompilerToolkit/CdlTkProcess.h" |
|
18 #include <algorithm> |
|
19 using namespace std; |
|
20 |
|
21 namespace CdlCompilerToolkit { |
|
22 |
|
23 // |
|
24 // CCdlTkApiListComparator |
|
25 // |
|
26 |
|
27 class CCdlTkApiListComparator |
|
28 { |
|
29 public: |
|
30 CCdlTkApiListComparator(CCdlTkApiList::const_iterator& aIter) : iIter(aIter) {} |
|
31 bool operator()(const CCdlTkApi* aApi) { return *aApi == **iIter; } |
|
32 CCdlTkApiList::const_iterator& iIter; |
|
33 }; |
|
34 |
|
35 |
|
36 // |
|
37 // CCdlTkApiChecker |
|
38 // |
|
39 |
|
40 CCdlTkApiChecker::CCdlTkApiChecker(const CCdlTkInterface& aLeft, |
|
41 const CCdlTkInterface& aRight, |
|
42 MCdlTkApiCheckObserver& aObserver) |
|
43 : iLeft(aLeft), iRight(aRight), iObserver(aObserver) |
|
44 { |
|
45 } |
|
46 |
|
47 CCdlTkApiChecker::~CCdlTkApiChecker() |
|
48 { |
|
49 } |
|
50 |
|
51 void CCdlTkApiChecker::Process() |
|
52 { |
|
53 iObserver.StartCheck(); |
|
54 |
|
55 const CCdlTkApiList& leftList = iLeft.ApiList(); |
|
56 const CCdlTkApiList& rightList = iRight.ApiList(); |
|
57 |
|
58 CApiListIter posLeft = leftList.begin(); |
|
59 CApiListIter posRight = rightList.begin(); |
|
60 CApiListIter leftEnd = leftList.end(); |
|
61 CApiListIter rightEnd = rightList.end(); |
|
62 |
|
63 while (posLeft!=leftEnd && posRight!=rightEnd) |
|
64 { |
|
65 // if left and right APIs don't match, |
|
66 // move the iterators till they do, or they hit the end |
|
67 if (**posLeft != **posRight) |
|
68 ReSync(posLeft, posRight, leftEnd, rightEnd); |
|
69 |
|
70 if (posLeft == leftEnd || posRight == rightEnd) |
|
71 { |
|
72 // if either iterator hits the end, fail everything remaining |
|
73 FailLeft(posLeft, leftEnd); |
|
74 FailRight(posRight, rightEnd); |
|
75 } |
|
76 else |
|
77 { |
|
78 // the APIs match, so tell the observer and move on |
|
79 iObserver.ApiInBoth(**posLeft); |
|
80 ++posLeft; |
|
81 ++posRight; |
|
82 } |
|
83 } |
|
84 |
|
85 iObserver.CheckComplete(); |
|
86 } |
|
87 |
|
88 // This function moves the iterators posLeft and posRight onwards till they |
|
89 // match APIs again, or they hit the ends. |
|
90 void CCdlTkApiChecker::ReSync(CApiListIter& posLeft, CApiListIter& posRight, |
|
91 const CApiListIter& leftEnd, const CApiListIter& rightEnd) const |
|
92 { |
|
93 // lookaheadLeft and lookaheadRight are how far we are looking ahead for a match |
|
94 CApiListIter lookaheadLeft = posLeft; |
|
95 CApiListIter lookaheadRight = posRight; |
|
96 |
|
97 // predicates for finding an API in a range |
|
98 CCdlTkApiListComparator chkContainsLeft(lookaheadLeft); |
|
99 CCdlTkApiListComparator chkContainsRight(lookaheadRight); |
|
100 |
|
101 // keep going till we get a match or reach the end |
|
102 for (;;) |
|
103 { |
|
104 // move lookahead iterators on one step |
|
105 ++lookaheadLeft; |
|
106 ++lookaheadRight; |
|
107 |
|
108 // stop and fail if we've hit the end on the left |
|
109 if (lookaheadLeft == leftEnd) |
|
110 { |
|
111 FailLeft(posLeft, leftEnd); |
|
112 break; |
|
113 } |
|
114 |
|
115 // stop and fail if we've hit the end on the right |
|
116 if (lookaheadRight == rightEnd) |
|
117 { |
|
118 FailRight(posRight, rightEnd); |
|
119 break; |
|
120 } |
|
121 |
|
122 // look through LHS lookahead range for the RHS API at the lookahead position |
|
123 CApiListIter foundLeft = find_if(posLeft, lookaheadLeft+1, chkContainsRight); |
|
124 if (foundLeft != lookaheadLeft+1) |
|
125 { |
|
126 // found a match, fail everything up till the match position and stop |
|
127 FailLeft(posLeft, foundLeft); |
|
128 FailRight(posRight, lookaheadRight); |
|
129 break; |
|
130 } |
|
131 |
|
132 // look through RHS lookahead range for the LHS API at the lookahead position |
|
133 CApiListIter foundRight = find_if(posRight, lookaheadRight+1, chkContainsLeft); |
|
134 if (foundRight != lookaheadRight+1) |
|
135 { |
|
136 // found a match, fail everything up till the match position and stop |
|
137 FailLeft(posLeft, lookaheadLeft); |
|
138 FailRight(posRight, foundRight); |
|
139 break; |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 void CCdlTkApiChecker::FailLeft(CApiListIter& aFrom, const CApiListIter& aTo) const |
|
145 { |
|
146 while (aFrom != aTo) |
|
147 { |
|
148 iObserver.ApiNotInRight(**aFrom); |
|
149 ++aFrom; |
|
150 } |
|
151 } |
|
152 |
|
153 void CCdlTkApiChecker::FailRight(CApiListIter& aFrom, const CApiListIter& aTo) const |
|
154 { |
|
155 while (aFrom != aTo) |
|
156 { |
|
157 iObserver.ApiNotInLeft(**aFrom); |
|
158 ++aFrom; |
|
159 } |
|
160 } |
|
161 |
|
162 } // end of namespace CdlCompilerToolkit |