|
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 "LayCdl2Inst.h" |
|
24 #include "LayoutCompilerErr.h" |
|
25 #include "LayoutParse.h" |
|
26 #include "CppWriter.h" |
|
27 #include "Lay2Cdl.h" |
|
28 #include <fstream> |
|
29 #include <algorithm> |
|
30 #include <iostream> |
|
31 #include "CodeGenConsts.h" |
|
32 using namespace std; |
|
33 using namespace CdlCompilerToolkit; |
|
34 |
|
35 typedef LayoutProcessArgsErr<LayoutAndCdlToCdlInstance> LayoutAndCdlToCdlInstanceArgsErr; |
|
36 |
|
37 |
|
38 class LayoutAndCdlToCdlInstanceChecker : public MCdlTkApiCheckObserver |
|
39 { |
|
40 private: |
|
41 void StartCheck(); |
|
42 void CheckComplete(); |
|
43 void ApiInBoth(const CCdlTkApi& aApi); |
|
44 void ApiNotInLeft(const CCdlTkApi& aApi); |
|
45 void ApiNotInRight(const CCdlTkApi& aApi); |
|
46 |
|
47 private: |
|
48 int iNotInLeft; |
|
49 int iNotInRight; |
|
50 }; |
|
51 |
|
52 |
|
53 void LayoutAndCdlToCdlInstanceChecker::StartCheck() |
|
54 { |
|
55 iNotInLeft = 0; |
|
56 iNotInRight = 0; |
|
57 } |
|
58 |
|
59 void LayoutAndCdlToCdlInstanceChecker::CheckComplete() |
|
60 { |
|
61 if (iNotInLeft) |
|
62 cout << "Layout is partial implementation of interface" << endl; |
|
63 if (iNotInRight) |
|
64 throw CdlTkAssert("Layout interface check failed"); |
|
65 } |
|
66 |
|
67 void LayoutAndCdlToCdlInstanceChecker::ApiInBoth(const CCdlTkApi& /*aApi*/) |
|
68 { |
|
69 } |
|
70 |
|
71 void LayoutAndCdlToCdlInstanceChecker::ApiNotInLeft(const CCdlTkApi& /*aApi*/) |
|
72 { |
|
73 iNotInLeft++; |
|
74 } |
|
75 |
|
76 void LayoutAndCdlToCdlInstanceChecker::ApiNotInRight(const CCdlTkApi& aApi) |
|
77 { |
|
78 iNotInRight++; |
|
79 cerr << aApi.Name() << " not in interface" << endl; |
|
80 } |
|
81 |
|
82 |
|
83 int LayoutAndCdlToCdlInstance::Process(const vector<string>& args) |
|
84 { |
|
85 if (args.size() < 5 || args.size()%2 == 0) |
|
86 throw LayoutAndCdlToCdlInstanceArgsErr(); |
|
87 |
|
88 string cdlName = args[2]; |
|
89 CCdlTkCdlFileParser parser(cdlName); |
|
90 auto_ptr<CCdlTkInterface> iface(parser.LoadAndParse(true)); |
|
91 |
|
92 LayoutAndCdlToCdlInstance process(*iface); |
|
93 |
|
94 TLayout* base = NULL; |
|
95 for (int arg = 3; arg < args.size(); arg += 2) |
|
96 { |
|
97 string layoutName = args[arg]; |
|
98 string instName = args[arg+1]; |
|
99 auto_ptr<TLayParseLayout> layoutParse = TLayParseLayout::Parse(layoutName); |
|
100 auto_ptr<TLayout> layout(layoutParse.get()); |
|
101 layoutParse.release(); |
|
102 if (base) |
|
103 { |
|
104 auto_ptr<TLayout> newLayout(new TLayout(*base)); |
|
105 newLayout->Merge(TLayout::KMergeModeVariant, *layout); |
|
106 layout = newLayout; |
|
107 } |
|
108 else |
|
109 { |
|
110 base = layout.get(); |
|
111 } |
|
112 process.AddLayout(layout, instName); |
|
113 } |
|
114 |
|
115 process.WriteInstances(); |
|
116 |
|
117 return 0; |
|
118 } |
|
119 |
|
120 void LayoutAndCdlToCdlInstance::ShowHelp(ostream& stream) |
|
121 { |
|
122 stream << "LayCdl2Inst <cdlName> (<layoutName> <instanceName>)+ " << endl; |
|
123 stream << " Creates CDL instances containing the layout data." << endl; |
|
124 stream << " All layout instances must conform to the CDL interface." << endl; |
|
125 stream << " If more than one layout is supplied, subsequent ones are treated as" << endl; |
|
126 stream << " variants of the first." << endl; |
|
127 } |
|
128 |
|
129 void LayoutAndCdlToCdlInstance::CheckLayoutAgainstInterface(const TLayout& aLayout, const CCdlTkInterface& aIface) |
|
130 { |
|
131 auto_ptr<CCdlTkInterface> layIface = LayoutToCdl::LayoutToInterface(aLayout); |
|
132 LayoutAndCdlToCdlInstanceChecker checker; |
|
133 CCdlTkApiChecker check(*layIface, aIface, checker); |
|
134 check.Process(); |
|
135 } |
|
136 |
|
137 LayoutAndCdlToCdlInstance::LayoutAndCdlToCdlInstance(CCdlTkInterface& aInterface) |
|
138 : iInterface(aInterface) |
|
139 { |
|
140 } |
|
141 |
|
142 LayoutAndCdlToCdlInstance::~LayoutAndCdlToCdlInstance() |
|
143 { |
|
144 for (CLayouts::iterator pLayout = iLayouts.begin(); pLayout != iLayouts.end(); ++pLayout) |
|
145 delete *pLayout; |
|
146 } |
|
147 |
|
148 void LayoutAndCdlToCdlInstance::AddLayout(auto_ptr<TLayout>& aLayout, const string& aInstName) |
|
149 { |
|
150 CLayoutToInst* base = NULL; |
|
151 if (iLayouts.size()) |
|
152 base = iLayouts[0]; |
|
153 auto_ptr<CLayoutToInst> p(new CLayoutToInst(base, iInterface, aLayout, aInstName)); |
|
154 iLayouts.push_back(p.get()); |
|
155 p.release(); |
|
156 } |
|
157 |
|
158 void LayoutAndCdlToCdlInstance::WriteInstances() |
|
159 { |
|
160 CLayouts::iterator pLayout = iLayouts.begin(); |
|
161 CLayouts::iterator end = iLayouts.end(); |
|
162 |
|
163 if (pLayout!=end) |
|
164 (*pLayout)->Process(); |
|
165 |
|
166 for (; pLayout != end; ++pLayout) |
|
167 { |
|
168 CCdlTkWriteInstance writer((*pLayout)->Instance()); |
|
169 writer.Process(); |
|
170 } |
|
171 } |
|
172 |
|
173 |
|
174 CLayoutToInst::CLayoutToInst(CLayoutToInst* aBase, CCdlTkInterface& aInterface, auto_ptr<TLayout>& aLayout, const string& aInstName) |
|
175 : iBase(aBase), iInterface(aInterface), iLayout(*aLayout), iInstName(aInstName) |
|
176 { |
|
177 iLayoutPtr = aLayout.get(); |
|
178 aLayout.release(); |
|
179 |
|
180 iInstance = new CCdlTkInstance(iInterface); |
|
181 iInstance->SetName(aInstName); |
|
182 |
|
183 string extraCpp("#include <aknlayout2datadef.h>\n"); |
|
184 extraCpp += string("#include \"") + CdlTkUtil::ToLower(aBase ? aBase->FwdDeclName() : FwdDeclName()) + "\"\n"; |
|
185 iInstance->SetExtraCpp(extraCpp); |
|
186 |
|
187 for (TLayout::iterator pTab = iLayout.begin(); pTab != iLayout.end(); ++pTab) |
|
188 { |
|
189 AddTableToInstance(**pTab); |
|
190 } |
|
191 } |
|
192 |
|
193 CLayoutToInst::~CLayoutToInst() |
|
194 { |
|
195 delete iInstance; |
|
196 delete iLayoutPtr; |
|
197 } |
|
198 |
|
199 string CLayoutToInst::FwdDeclName() |
|
200 { |
|
201 if (iBase) |
|
202 return iBase->FwdDeclName(); |
|
203 else |
|
204 return iInstName + ".FwdDecl.h"; |
|
205 } |
|
206 |
|
207 void CLayoutToInst::Process() |
|
208 { |
|
209 string fileName(FwdDeclName()); |
|
210 string interfaceNsName = iInterface.NamespaceName(); |
|
211 |
|
212 ofstream stream; |
|
213 CCdlTkFileCleanup tempFile; |
|
214 CdlTkUtil::OpenTempOutput(stream, tempFile); |
|
215 |
|
216 WriteHeaderGuardStart(fileName, stream); |
|
217 stream << "namespace " << CdlTkUtil::ToCpp(iInstance->Name()) << endl; |
|
218 stream << "{" << endl; |
|
219 |
|
220 CCdlTkApiList& apiList = iInterface.ApiList(); |
|
221 for (CCdlTkApiList::iterator pApi = apiList.begin(); pApi != apiList.end(); ++pApi) |
|
222 { |
|
223 if ((*pApi)->IsFunc()) |
|
224 { |
|
225 stream << "extern " << interfaceNsName << "::" << (*pApi)->AsFunc().ApiNameAsTypeName() << " " << (*pApi)->Name() << ";" << endl; |
|
226 } |
|
227 else |
|
228 { |
|
229 string typeExt = "Imp"; |
|
230 if ((*pApi)->ReturnType() == KTypeLayoutTableLimits) |
|
231 typeExt = ""; |
|
232 stream << "extern " << (*pApi)->ReturnType() << typeExt << " const " << (*pApi)->Name() << ";" << endl; |
|
233 } |
|
234 } |
|
235 |
|
236 stream << "}" << endl << endl; |
|
237 WriteHeaderGuardEnd(fileName, stream); |
|
238 |
|
239 stream.close(); |
|
240 CdlTkUtil::ExportFile(tempFile, CdlTkUtil::OutputPath() + fileName); |
|
241 } |
|
242 |
|
243 CCdlTkInstance& CLayoutToInst::Instance() |
|
244 { |
|
245 return *iInstance; |
|
246 } |
|
247 |
|
248 void CLayoutToInst::AddTableToInstance(TLayoutTable& aTable) |
|
249 { |
|
250 for (TLayoutTable::iterator pLine = aTable.begin(); pLine != aTable.end(); ++pLine) |
|
251 { |
|
252 TLayoutLine& line = **pLine; |
|
253 if (line.iIsMergedIdentical) |
|
254 { |
|
255 string apiName = LayoutToCdl::LineApiName(line); |
|
256 AddFwdRefToInstance(apiName, false); |
|
257 |
|
258 string multilineApiName = KFuncMultiline + apiName; |
|
259 if (aTable.iType == TLayoutTable::ETextTable && |
|
260 line["B"].size() > 1 && |
|
261 HasApi(multilineApiName)) |
|
262 { |
|
263 AddFwdRefToInstance(multilineApiName, false); |
|
264 } |
|
265 } |
|
266 else |
|
267 { |
|
268 if (aTable.iType == TLayoutTable::EWindowTable) |
|
269 AddWindowLineToInstance(line); |
|
270 else |
|
271 AddTextLineToInstance(line); |
|
272 } |
|
273 } |
|
274 |
|
275 int tableNum = 0; |
|
276 for (TLayoutTable::TLayoutSubTables::const_iterator pSub = aTable.iSubTables.begin(); pSub != aTable.iSubTables.end(); ++pSub) |
|
277 { |
|
278 TLayoutTable::TLayoutSubTable& sub = **pSub; |
|
279 if (sub.iIsMergedIdentical) |
|
280 { |
|
281 AddFwdRefToInstance(LayoutToCdl::TableApiName(aTable, sub, tableNum)+KFuncLimitsSuffix, false); |
|
282 AddFwdRefToInstance(LayoutToCdl::TableApiName(aTable, sub, tableNum), false); |
|
283 } |
|
284 else |
|
285 { |
|
286 AddTableLimitsToInstance(aTable, sub, tableNum); |
|
287 string tableType = KTypeTextLineLayout; |
|
288 if (aTable.iType == TLayoutTable::EWindowTable) |
|
289 tableType = KTypeWindowLineLayout; |
|
290 AddSubTableToInstance(tableType, aTable, sub, tableNum); |
|
291 } |
|
292 tableNum++; |
|
293 } |
|
294 } |
|
295 |
|
296 void CLayoutToInst::AddWindowLineToInstance(TLayoutLine& aLine) |
|
297 { |
|
298 string apiName = LayoutToCdl::LineApiName(aLine); |
|
299 if (!HasApi(apiName)) |
|
300 return; |
|
301 CCdlTkImplementation& imp = FindImp(apiName); |
|
302 SetFuncLine(imp, aLine, KTypeWindowLineLayout, KWindowOutputOrder, KWindowOutputOrderSize, "", ""); |
|
303 } |
|
304 |
|
305 const string KMultiLineTextLineExtra = "\ |
|
306 \tline.iB = KB[0];\n\ |
|
307 \tline.iBaselineSkip = KB[1]-KB[0];\n\ |
|
308 \tline.iNumberOfLinesShown = aNumberOfLinesShown;\n"; |
|
309 |
|
310 const string KTextLineExtra = "\ |
|
311 \tline.iBaselineSkip = 0;\n\ |
|
312 \tline.iNumberOfLinesShown = 1;\n"; |
|
313 |
|
314 void CLayoutToInst::AddTextLineToInstance(TLayoutLine& aLine) |
|
315 { |
|
316 string apiName = LayoutToCdl::LineApiName(aLine); |
|
317 if (!HasApi(apiName)) |
|
318 return; |
|
319 CCdlTkImplementation& imp = FindImp(apiName); |
|
320 SetFuncLine(imp, aLine, KTypeTextLineLayout, KTextOutputOrder, KTextOutputOrderSize, "", KTextLineExtra); |
|
321 if (aLine["B"].size() > 1) |
|
322 { |
|
323 string preExtra = "\tTInt " + KParamNameB + " = 0;\n"; |
|
324 if (aLine["B"].ParamName() != KParamNameB) |
|
325 preExtra = ""; |
|
326 string apiName = KFuncMultiline + imp.Name(); |
|
327 if (HasApi(apiName)) |
|
328 { |
|
329 CCdlTkImplementation& multiLineImp = FindImp(KFuncMultiline + imp.Name()); |
|
330 SetFuncLine(multiLineImp, aLine, KTypeMultiLineTextLayout, KTextOutputOrder, KTextOutputOrderSize, preExtra, KMultiLineTextLineExtra); |
|
331 } |
|
332 } |
|
333 } |
|
334 |
|
335 bool CLayoutToInst::HasApi(const string& aName) |
|
336 { |
|
337 return iInterface.ApiList().Find(aName) != 0; |
|
338 } |
|
339 |
|
340 CCdlTkImplementation& CLayoutToInst::FindImp(const string& aName) |
|
341 { |
|
342 CCdlTkImplementation* impl = iInstance->Impl().Find(aName); |
|
343 if (!impl) |
|
344 throw NotFoundErr(aName + " in interface " + iInterface.FileName()); |
|
345 return *impl; |
|
346 } |
|
347 |
|
348 |
|
349 // subtable function uses the main table of pointers, with a mask to ensure that only correct lines are accessed |
|
350 // which are indexed by aLineIndex |
|
351 |
|
352 const string KSubTableImpl = "\ |
|
353 #TYPE #NAME#PARAMLIST\n\ |
|
354 \t{\n\ |
|
355 \tstatic #PTRTYPE const * const KSubTableImpl = (#PTRTYPE const * const)&KCdlImpl.#FIRST_MEMBER;\n\ |
|
356 \tASSERT(0<=" + KParamLineIndex + " && " + KParamLineIndex + "<32 && ((1<<" + KParamLineIndex + ") & #VALID_INDEX));\n\ |
|
357 \t#PTRTYPE KImpl = KSubTableImpl[" + KParamLineIndex + "];\n\ |
|
358 \treturn #EVAL;\n\ |
|
359 \t}"; |
|
360 |
|
361 const string KSubTableFuncEval = "(*KImpl)(#PARAMNAMES)"; |
|
362 const string KSubTableDataEval = "*KImpl"; |
|
363 |
|
364 void CLayoutToInst::AddSubTableToInstance(const string& aType, TLayoutTable& aTable, TLayoutTable::TLayoutSubTable& aSubTable, int aTableNum) |
|
365 { |
|
366 string apiName = LayoutToCdl::TableApiName(aTable, aSubTable, aTableNum); |
|
367 if (!HasApi(apiName)) |
|
368 return; |
|
369 |
|
370 CCdlTkImplementation& imp = FindImp(apiName); |
|
371 const CCdlTkFunctionApi& api = imp.Api().AsFunc(); |
|
372 const CCdlTkApiParams& params = api.Params(); |
|
373 |
|
374 TLayoutLine& line = *aTable[aSubTable[0]]; |
|
375 CCdlTkImplementation& lineImp = FindImp(LayoutToCdl::LineApiName(line)); |
|
376 const CCdlTkApi& lineApi = lineImp.Api(); |
|
377 |
|
378 string ptrType; |
|
379 if (lineApi.IsFunc()) |
|
380 ptrType = iInterface.NamespaceName() + "::" + lineApi.PointerType(); |
|
381 else |
|
382 ptrType = lineApi.PointerType(); |
|
383 |
|
384 int valid = 0; |
|
385 for (int ii=0; ii<aTable.size(); ii++) |
|
386 { |
|
387 if (find(aSubTable.begin(), aSubTable.end(), ii) != aSubTable.end()) |
|
388 { |
|
389 valid |= 1<<ii; |
|
390 } |
|
391 } |
|
392 |
|
393 string firstMember = LayoutToCdl::LineApiName(*aTable[0]); |
|
394 |
|
395 CdlTkUtil::CReplaceSet implSet; |
|
396 implSet.Add("#TYPE", aType); |
|
397 implSet.Add("#NAME", imp.Name()); |
|
398 implSet.Add("#PARAMLIST", api.ParamsTypeAndNameList()); |
|
399 implSet.Add("#PTRTYPE", ptrType); |
|
400 implSet.Add("#FIRST_MEMBER", firstMember); |
|
401 implSet.Add("#VALID_INDEX", CdlTkUtil::IntToHexString(valid)); |
|
402 implSet.Add("#EVAL", lineApi.IsFunc() ? |
|
403 CdlTkUtil::Replace("#PARAMNAMES", lineApi.AsFunc().ParamNameList(), KSubTableFuncEval) : |
|
404 KSubTableDataEval); |
|
405 string impl = CdlTkUtil::MultiReplace(implSet, KSubTableImpl); |
|
406 |
|
407 imp.SetTemplatePointerReference(); |
|
408 imp.SetDefinition(impl); |
|
409 } |
|
410 |
|
411 const string KTableLimitsImpl = |
|
412 KTypeLayoutTableLimits + " #NAME()\n\ |
|
413 \t{\n\ |
|
414 \tconst " + KTypeLayoutTableLimits + " limits = {#FIRST, #LAST};\n\ |
|
415 \treturn limits;\n\ |
|
416 \t}"; |
|
417 |
|
418 void CLayoutToInst::AddTableLimitsToInstance(TLayoutTable& aTable, TLayoutTable::TLayoutSubTable& aSubTable, int aTableNum) |
|
419 { |
|
420 string apiName = LayoutToCdl::TableApiName(aTable, aSubTable, aTableNum)+KFuncLimitsSuffix; |
|
421 if (!HasApi(apiName)) |
|
422 return; |
|
423 |
|
424 CCdlTkImplementation& imp = FindImp(apiName); |
|
425 |
|
426 int first = *aSubTable.begin(); |
|
427 int last = *aSubTable.rbegin(); |
|
428 |
|
429 CdlTkUtil::CReplaceSet implSet; |
|
430 implSet.Add("#NAME", imp.Name()); |
|
431 implSet.Add("#FIRST", CdlTkUtil::IntToString(first)); |
|
432 implSet.Add("#LAST", CdlTkUtil::IntToString(last)); |
|
433 string impl = CdlTkUtil::MultiReplace(implSet, KTableLimitsImpl); |
|
434 |
|
435 imp.SetTemplatePointerReference(); |
|
436 imp.SetDefinition(impl); |
|
437 } |
|
438 |
|
439 |
|
440 // data implementation is a simple const static data declaration |
|
441 |
|
442 const string KDataImpl = "const #TYPEImp #NAME = {#DATA};"; |
|
443 const string KDataPtr = "(#TYPE*)&#NAME"; |
|
444 |
|
445 void CLayoutToInst::SetDataLine(CCdlTkImplementation& aImp, TLayoutLine& aLine, const string& aType, const string aOutputOrder[], int aOutputOrderSize) |
|
446 { |
|
447 string data; |
|
448 for (int ii=0; ii<aOutputOrderSize; ii++) |
|
449 { |
|
450 if (ii != 0) |
|
451 data += ","; |
|
452 string value = aLine[aOutputOrder[ii]][0]; |
|
453 CdlTkUtil::AppendString(data, TValues::CppValue(value)); |
|
454 } |
|
455 |
|
456 CdlTkUtil::CReplaceSet implSet; |
|
457 implSet.Add("#TYPE", aType); |
|
458 implSet.Add("#NAME", aImp.Name()); |
|
459 implSet.Add("#DATA", data); |
|
460 string impl = CdlTkUtil::MultiReplace(implSet, KDataImpl); |
|
461 |
|
462 CdlTkUtil::CReplaceSet ptrSet; |
|
463 ptrSet.Add("#TYPE", aType); |
|
464 ptrSet.Add("#NAME", aImp.Name()); |
|
465 string ptr = CdlTkUtil::MultiReplace(ptrSet, KDataPtr); |
|
466 |
|
467 aImp.SetPointerReference(ptr); |
|
468 aImp.SetDefinition(impl); |
|
469 } |
|
470 |
|
471 |
|
472 // function implementation starts with asserts for parameter ranges and |
|
473 // tables of values for the parameterised cells. |
|
474 // The actual structure is initialised for the fixed values and indexed lookups |
|
475 // on the tables |
|
476 |
|
477 const string KFunctionImpl = "\ |
|
478 #TYPE #NAME#PARAMTYPEANDNAMELIST\n\ |
|
479 \t{\n\ |
|
480 #PRE_EXTRA\ |
|
481 #ASSERTS\ |
|
482 #TABLES\ |
|
483 \t#TYPEImp line = {#INIT};\n\ |
|
484 #LOOKUPS\ |
|
485 #POST_EXTRA\ |
|
486 #RECT_ADJUST\ |
|
487 \treturn line;\n\ |
|
488 \t}"; |
|
489 |
|
490 const string KFunctionAssert = "\tASSERT(0<=#PARAMNAME && #PARAMNAME<#PARAMLIMIT);\n"; |
|
491 const string KFunctionTable = "\tconst static TInt16 K#TABLENAME[#PARAMLIMIT] = {#VALUES};\n"; |
|
492 const string KFunctionLookup = "\tline.i#TABLENAME = K#TABLENAME[#PARAMNAME];\n"; |
|
493 const string KFunctionRect = "\tline.SetAllParentOffsets(" + KParamParentRect + ");\n"; |
|
494 |
|
495 void CLayoutToInst::SetFuncLine(CCdlTkImplementation& aImp, TLayoutLine& aLine, const string& aType, const string aOutputOrder[], int aOutputOrderSize, const string& aPreExtra, const string& aPostExtra) |
|
496 { |
|
497 const CCdlTkFunctionApi& api = aImp.Api().AsFunc(); |
|
498 const CCdlTkApiParams& params = api.Params(); |
|
499 |
|
500 string asserts; |
|
501 string tables; |
|
502 string init; |
|
503 string lookups; |
|
504 for (int ii=0; ii<aOutputOrderSize; ii++) |
|
505 { |
|
506 TValues& values = aLine[aOutputOrder[ii]]; |
|
507 const string& paramName = values.ParamName(); |
|
508 const string& paramLimit = CdlTkUtil::IntToString(values.size()); |
|
509 const string& tableName = aOutputOrder[ii]; |
|
510 |
|
511 if (ii != 0) |
|
512 init += ","; |
|
513 if (values.size() > 1) |
|
514 { |
|
515 string v; |
|
516 for (TValues::iterator pVal = values.begin(); pVal != values.end(); ++pVal) |
|
517 { |
|
518 if (pVal != values.begin()) |
|
519 v += ","; |
|
520 v += TValues::CppValue(*pVal); |
|
521 } |
|
522 |
|
523 CdlTkUtil::CReplaceSet replaceSet; |
|
524 replaceSet.Add("#PARAMNAME", paramName); |
|
525 replaceSet.Add("#PARAMLIMIT", paramLimit); |
|
526 replaceSet.Add("#TABLENAME", tableName); |
|
527 replaceSet.Add("#VALUES", v); |
|
528 |
|
529 CdlTkUtil::AppendString(asserts, CdlTkUtil::MultiReplace(replaceSet, KFunctionAssert)); |
|
530 CdlTkUtil::AppendString(tables, CdlTkUtil::MultiReplace(replaceSet, KFunctionTable)); |
|
531 CdlTkUtil::AppendString(lookups, CdlTkUtil::MultiReplace(replaceSet, KFunctionLookup)); |
|
532 CdlTkUtil::AppendString(init, "0"); |
|
533 } |
|
534 else |
|
535 { |
|
536 CdlTkUtil::AppendString(init, TValues::CppValue(values[0])); |
|
537 } |
|
538 } |
|
539 |
|
540 string paramTypeAndNameList(api.ParamsTypeAndNameList()); |
|
541 if (aLine.iIsMirroredHorizontally) |
|
542 MirrorParamNames(paramTypeAndNameList); |
|
543 |
|
544 CdlTkUtil::CReplaceSet implSet; |
|
545 implSet.Add("#TYPE", aType); |
|
546 implSet.Add("#NAME", api.Name()); |
|
547 implSet.Add("#PARAMTYPEANDNAMELIST", paramTypeAndNameList); |
|
548 implSet.Add("#PRE_EXTRA", aPreExtra); |
|
549 implSet.Add("#ASSERTS", asserts); |
|
550 implSet.Add("#TABLES", tables); |
|
551 implSet.Add("#INIT", init); |
|
552 implSet.Add("#LOOKUPS", lookups); |
|
553 implSet.Add("#POST_EXTRA", aPostExtra); |
|
554 implSet.Add("#RECT_ADJUST", aLine.iNeedsP ? KFunctionRect : ""); |
|
555 string impl = CdlTkUtil::MultiReplace(implSet, KFunctionImpl); |
|
556 |
|
557 aImp.SetTemplatePointerReference(); |
|
558 aImp.SetDefinition(impl); |
|
559 } |
|
560 |
|
561 void CLayoutToInst::MirrorParamNames(std::string& aNames) |
|
562 { |
|
563 aNames = CdlTkUtil::Replace(KParamNameL, "__tmp__", aNames); |
|
564 aNames = CdlTkUtil::Replace(KParamNameR, KParamNameL, aNames); |
|
565 aNames = CdlTkUtil::Replace("__tmp__", KParamNameR, aNames); |
|
566 } |
|
567 |
|
568 void CLayoutToInst::AddFwdRefToInstance(const string& aName, bool aCast) |
|
569 { |
|
570 string ns(CdlTkUtil::ToCpp(iBase->iInstance->Name())); |
|
571 if (!HasApi(aName)) |
|
572 return; |
|
573 |
|
574 CCdlTkImplementation& imp = FindImp(aName); |
|
575 string ptr; |
|
576 if (aCast) |
|
577 ptr = string("(") + imp.Api().ReturnType() + "*)"; |
|
578 ptr += string("&") + ns + "::" + aName; |
|
579 imp.SetPointerReference(ptr); |
|
580 } |
|
581 |
|
582 |
|
583 |