|
1 /* |
|
2 * Copyright (c) 2002-2004 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 |
|
18 |
|
19 |
|
20 // disable "identifier was truncated to '255' characters in the browser information" warning |
|
21 #pragma warning (disable:4786) |
|
22 |
|
23 #include "LayCdlCheck.h" |
|
24 #include <iostream> |
|
25 #include "LayoutCompilerErr.h" |
|
26 #include "LayoutParse.h" |
|
27 #include "Lay2Cdl.h" |
|
28 #include <cdlcompilertoolkit/cdltkprocess.h> |
|
29 using namespace std; |
|
30 using namespace CdlCompilerToolkit; |
|
31 |
|
32 |
|
33 typedef LayoutProcessArgsErr<LayCdlCheck> LayCdlCheckArgsErr; |
|
34 |
|
35 const string KDefaultLayCdlCheckOptions = "lcm"; |
|
36 |
|
37 int LayCdlCheck::Process(const vector<string>& args) |
|
38 { |
|
39 if (args.size() < 4) |
|
40 throw LayCdlCheckArgsErr(); |
|
41 |
|
42 int nextArg = 2; |
|
43 string opt = args[nextArg]; |
|
44 if (opt.size() >= 2 && opt.substr(0,2) == "-o") |
|
45 { |
|
46 nextArg++; |
|
47 opt = opt.substr(2); |
|
48 } |
|
49 else |
|
50 { |
|
51 opt = KDefaultLayCdlCheckOptions; |
|
52 } |
|
53 |
|
54 string layoutName = args[nextArg++]; |
|
55 auto_ptr<TLayParseLayout> layout(TLayParseLayout::Parse(layoutName)); |
|
56 auto_ptr<CCdlTkInterface> iface(new CCdlTkInterface); |
|
57 CCdlTkApiList& apiList = iface->ApiList(); |
|
58 auto_ptr<CCdlTkInterface> xIface(new CCdlTkInterface); |
|
59 CCdlTkApiList& xApiList = xIface->ApiList(); |
|
60 |
|
61 for (int arg = nextArg; arg < args.size(); arg++) |
|
62 { |
|
63 string fileName = args[arg]; |
|
64 if (fileName.size() < 4) |
|
65 throw LayCdlCheckArgsErr(); |
|
66 string ext = CdlTkUtil::ToLower(fileName.substr(fileName.size()-4)); |
|
67 |
|
68 if (ext == ".lay") |
|
69 { |
|
70 auto_ptr<TLayParseLayout> nextLayout(TLayParseLayout::Parse(fileName)); |
|
71 layout->Merge(TLayout::KMergeModeVariant, *nextLayout); |
|
72 } |
|
73 else if (ext == ".cdl") |
|
74 { |
|
75 CCdlTkApiList* pApiList = &apiList; |
|
76 if (fileName.substr(0,2) == "-x") |
|
77 { |
|
78 pApiList = &xApiList; |
|
79 fileName = fileName.substr(2); |
|
80 } |
|
81 CCdlTkCdlFileParser parser(fileName); |
|
82 auto_ptr<CCdlTkInterface> nextIface(parser.LoadAndParse(true)); |
|
83 CCdlTkApiList& nextApi = nextIface->ApiList(); |
|
84 for (CCdlTkApiList::iterator pApi = nextApi.begin(); pApi != nextApi.end(); ++pApi) |
|
85 pApiList->push_back((*pApi)->Clone(*iface)); |
|
86 } |
|
87 else |
|
88 throw LayCdlCheckArgsErr(); |
|
89 } |
|
90 |
|
91 LayCdlCheck process(*layout, *iface, *xIface, opt); |
|
92 process.Process(); |
|
93 |
|
94 return 0; |
|
95 } |
|
96 |
|
97 void LayCdlCheck::ShowHelp(ostream& stream) |
|
98 { |
|
99 stream << "LayCdlCheck [-o[glcm]] <layoutName>* <cdlName>* [-x<cdlName>*]" << endl; |
|
100 stream << " Compare API for lay files against CDL interfaces" << endl; |
|
101 stream << " -o[glcm] (default = -olcm) - show output for:" << endl; |
|
102 stream << " g = good matches" << endl; |
|
103 stream << " l = lay file only" << endl; |
|
104 stream << " c = CDL interface only" << endl; |
|
105 stream << " m = mismatches" << endl; |
|
106 stream << " Where multiple <layoutName> are specified, the layouts are merged with variant mode." << endl; |
|
107 stream << " Where multiple <cdlName> are specified, the CDL interfaces are added together." << endl; |
|
108 stream << " -x<cdlName> - exclude APIs in <cdlName> from the report." << endl; |
|
109 } |
|
110 |
|
111 |
|
112 LayCdlCheck::LayCdlCheck(TLayout& aLayout, CCdlTkInterface& aInterface, CCdlTkInterface& aExcluded, const string& aOpt) |
|
113 : iLayout(aLayout), iInterface(aInterface), iExcluded(aExcluded), iLayoutInterface(0), iOpt(aOpt) |
|
114 { |
|
115 } |
|
116 |
|
117 LayCdlCheck::~LayCdlCheck() |
|
118 { |
|
119 delete iLayoutInterface; |
|
120 } |
|
121 |
|
122 void LayCdlCheck::Process() |
|
123 { |
|
124 delete iLayoutInterface; |
|
125 iLayoutInterface = 0; |
|
126 |
|
127 auto_ptr<CCdlTkInterface> iface(LayoutToCdl::LayoutToInterface(iLayout)); |
|
128 iLayoutInterface = iface.get(); |
|
129 iface.release(); |
|
130 |
|
131 vector<string> good; |
|
132 vector<string> onlyLay; |
|
133 vector<string> onlyCdl; |
|
134 vector<string> paramMismatch; |
|
135 |
|
136 Compare(good, onlyLay, onlyCdl, paramMismatch); |
|
137 |
|
138 if (HasOpt('g')) |
|
139 Report("Good API", good); |
|
140 if (HasOpt('l')) |
|
141 Report("API only in lay file", onlyLay); |
|
142 if (HasOpt('c')) |
|
143 Report("API only in CDL file", onlyCdl); |
|
144 if (HasOpt('m')) |
|
145 Report("API with mismatched interface", paramMismatch); |
|
146 } |
|
147 |
|
148 void LayCdlCheck::Compare(vector<string>& aGood, vector<string>& aOnlyLay, vector<string>& aOnlyCdl, vector<string>& aParamMismatch) |
|
149 { |
|
150 CCdlTkApiList& layApi = iLayoutInterface->ApiList(); |
|
151 CCdlTkApiList& cdlApi = iInterface.ApiList(); |
|
152 CCdlTkApiList& xApi = iExcluded.ApiList(); |
|
153 for (CCdlTkApiList::iterator pLay = layApi.begin(); pLay != layApi.end(); ++pLay) |
|
154 { |
|
155 const string& name = (*pLay)->Name(); |
|
156 CCdlTkApi* xCdl = xApi.Find(name); |
|
157 if (xCdl && (*xCdl) == (**pLay)) |
|
158 continue; |
|
159 |
|
160 string fullName = (*pLay)->ReturnType() + " " + name + (*pLay)->ParamsTypeAndNameList() + ";"; |
|
161 CCdlTkApi* cdl = cdlApi.Find(name); |
|
162 if (cdl) |
|
163 { |
|
164 if (*cdl == **pLay) |
|
165 { |
|
166 aGood.push_back(fullName); |
|
167 } |
|
168 else |
|
169 { |
|
170 aParamMismatch.push_back(fullName + " vs " + cdl->ParamsTypeAndNameList()); |
|
171 } |
|
172 } |
|
173 else |
|
174 { |
|
175 aOnlyLay.push_back(fullName); |
|
176 } |
|
177 } |
|
178 |
|
179 for (CCdlTkApiList::iterator pCdl = cdlApi.begin(); pCdl != cdlApi.end(); ++pCdl) |
|
180 { |
|
181 const string& name = (*pCdl)->Name(); |
|
182 string fullName = (*pCdl)->ReturnType() + " " + name + (*pCdl)->ParamsTypeAndNameList(); |
|
183 CCdlTkApi* lay = layApi.Find(name); |
|
184 if (!lay) |
|
185 { |
|
186 aOnlyCdl.push_back(fullName); |
|
187 } |
|
188 } |
|
189 } |
|
190 |
|
191 void LayCdlCheck::Report(const string& aTitle, vector<string>& aApi) |
|
192 { |
|
193 cout << aTitle << endl; |
|
194 for (vector<string>::iterator pApi = aApi.begin(); pApi != aApi.end(); ++pApi) |
|
195 { |
|
196 cout << *pApi << endl; |
|
197 } |
|
198 cout << endl; |
|
199 } |
|
200 |
|
201 bool LayCdlCheck::HasOpt(char c) |
|
202 { |
|
203 return iOpt.find(c) != string::npos; |
|
204 } |
|
205 |
|
206 |