|
1 /* |
|
2 * Copyright (c) 2006-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 |
|
18 |
|
19 #include "CmdGlobals.h" |
|
20 #ifdef __WIN__ |
|
21 #pragma warning(disable:4786) |
|
22 #endif |
|
23 |
|
24 #include <vector> |
|
25 #include <algorithm> |
|
26 #include "PlatformData.h" |
|
27 #include "XMLUtils.h" |
|
28 #include "XMLStringConst.h" |
|
29 #include "Utils.h" |
|
30 #include "BBCFileUtils.h" |
|
31 #include "HAException.h" |
|
32 |
|
33 |
|
34 const char* XML_FILE_ID_ATTRIBUTE = "id"; |
|
35 |
|
36 /** |
|
37 * Generic utility function, which checks whether the given object is |
|
38 * in the vector. |
|
39 */ |
|
40 template <typename C> |
|
41 inline bool IsObjectInVector(const vector<C>& v, const C& o) |
|
42 { |
|
43 return std::find(v.begin(), v.end(), o) != v.end(); |
|
44 } |
|
45 |
|
46 // Convert to proper dir-separator |
|
47 string& FixPathString(string& str) |
|
48 { |
|
49 string::size_type dirSepInd = str.find_first_of("\\/"); |
|
50 if( dirSepInd != string::npos && str.at(dirSepInd) != DIR_SEPARATOR ) |
|
51 { |
|
52 replaceChar(str, str.at(dirSepInd), DIR_SEPARATOR); |
|
53 } |
|
54 return str; |
|
55 } |
|
56 |
|
57 /** |
|
58 * |
|
59 */ |
|
60 ComponentFile::ComponentFile() |
|
61 : |
|
62 iComponent(0) |
|
63 {} |
|
64 |
|
65 /** |
|
66 * |
|
67 */ |
|
68 ComponentFile::ComponentFile(const string& ID, Component* comp) |
|
69 : |
|
70 iID(ID), |
|
71 iComponent(comp) |
|
72 { } |
|
73 |
|
74 /** |
|
75 * |
|
76 */ |
|
77 ComponentFile::ComponentFile(const ComponentFile &rhs) |
|
78 : |
|
79 iID(rhs.ID()), |
|
80 iName(rhs.FileName()), |
|
81 iPath(rhs.Path()), |
|
82 iComponent(rhs.GetComponent()) |
|
83 { } |
|
84 |
|
85 /** |
|
86 * |
|
87 */ |
|
88 ComponentFile::~ComponentFile() |
|
89 { } |
|
90 |
|
91 /** |
|
92 * |
|
93 */ |
|
94 const string& ComponentFile::ID() const |
|
95 { |
|
96 return iID; |
|
97 } |
|
98 |
|
99 /** |
|
100 * |
|
101 */ |
|
102 const string& ComponentFile::FileName() const |
|
103 { |
|
104 return iName; |
|
105 } |
|
106 |
|
107 /** |
|
108 * |
|
109 */ |
|
110 const string& ComponentFile::Path() const |
|
111 { |
|
112 return iPath; |
|
113 } |
|
114 |
|
115 /** |
|
116 * |
|
117 */ |
|
118 void ComponentFile::SetID(const string& ID) |
|
119 { |
|
120 iID = ID; |
|
121 } |
|
122 |
|
123 /** |
|
124 * |
|
125 */ |
|
126 void ComponentFile::SetFileName(const string& name) |
|
127 { |
|
128 iName = name; |
|
129 } |
|
130 |
|
131 /** |
|
132 * |
|
133 */ |
|
134 void ComponentFile::SetPath(const string& path) |
|
135 { |
|
136 iPath = path; |
|
137 } |
|
138 |
|
139 /** |
|
140 * |
|
141 */ |
|
142 Component* ComponentFile::GetComponent() const |
|
143 { |
|
144 return iComponent; |
|
145 } |
|
146 |
|
147 /** |
|
148 * |
|
149 */ |
|
150 void ComponentFile::SetComponent(Component* comp) |
|
151 { |
|
152 iComponent = comp; |
|
153 } |
|
154 |
|
155 /** |
|
156 * |
|
157 */ |
|
158 string ComponentFile::ForcedInclude() |
|
159 { |
|
160 return iForcedInclude; |
|
161 } |
|
162 |
|
163 pair<string,string>& ComponentFile::APIinfo() |
|
164 { |
|
165 return iApiInfo; |
|
166 } |
|
167 |
|
168 /** |
|
169 * |
|
170 */ |
|
171 const ComponentFile& ComponentFile::operator= (const ComponentFile& rhs) |
|
172 { |
|
173 if( &rhs != this ) |
|
174 { |
|
175 iID = rhs.ID(); |
|
176 iName = rhs.FileName(); |
|
177 iPath = rhs.Path(); |
|
178 iComponent = rhs.GetComponent(); |
|
179 } |
|
180 return *this; |
|
181 } |
|
182 |
|
183 /** |
|
184 * |
|
185 */ |
|
186 bool ComponentFile::operator== (const ComponentFile& rhs) const |
|
187 { |
|
188 return iID == rhs.ID() && |
|
189 // iName == rhs.iName && |
|
190 // iPath == rhs.iPath && |
|
191 iComponent == iComponent; |
|
192 } |
|
193 |
|
194 /** |
|
195 * |
|
196 */ |
|
197 void ComponentFile::ProcessAttributes(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node) |
|
198 { |
|
199 // Read "fileid"-attribute: |
|
200 const XMLCh* fileIdAttr = GetAttribute(node, XML_FILE_ID_ATTRIBUTE); |
|
201 if( fileIdAttr ) |
|
202 { |
|
203 string str(toString(fileIdAttr)); |
|
204 iID = FixPathString(toLower(str)); |
|
205 } |
|
206 } |
|
207 |
|
208 /** |
|
209 * Reads child elements from the parsed XML (DOM) data. This baseclass implementation |
|
210 * processes the "filename", "relativepath" and "include" elements, which are common |
|
211 * to all component files. |
|
212 */ |
|
213 bool ComponentFile::ProcessChildElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node, PlatformData* platform) |
|
214 { |
|
215 if( node->getNodeType() != DOMNode::ELEMENT_NODE ) |
|
216 return false; |
|
217 |
|
218 bool properChild = false; |
|
219 |
|
220 const XMLCh* elementtype = node->getNodeName(); |
|
221 if( elementtype ) |
|
222 { |
|
223 string elemtypeStr(toString(elementtype)); |
|
224 |
|
225 //Handle the API info. |
|
226 if( elemtypeStr == PLATFORM_ELEMENT_API_NAME ) |
|
227 { |
|
228 XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* apiNode = (DOMElement*)node; |
|
229 char* apiname = _X( apiNode->getAttribute( _X( "name" ) ) ); |
|
230 char* apiCategory = _X( apiNode->getAttribute( _X( "category" ) ) ); |
|
231 |
|
232 iApiInfo.first = apiname; |
|
233 iApiInfo.second = apiCategory; |
|
234 |
|
235 _XX(apiname); |
|
236 _XX(apiCategory); |
|
237 } |
|
238 if( elemtypeStr == PLATFORM_ELEMENT_INCLUDE ) |
|
239 { |
|
240 // Handle include element |
|
241 const XMLCh* nodeVal = node->getTextContent(); |
|
242 if( nodeVal ) |
|
243 { |
|
244 string tempStr(toString(nodeVal)); |
|
245 iIncludes.push_back(FixPathString(toLower(tempStr))); |
|
246 properChild = true; |
|
247 } |
|
248 } |
|
249 else if( elemtypeStr == PLATFORM_ELEMENT_INCLUDEPATH ) |
|
250 { |
|
251 // Include paths: |
|
252 const XMLCh* nodeVal = node->getTextContent(); |
|
253 if( nodeVal ) |
|
254 { |
|
255 string tempStr(toString(nodeVal)); |
|
256 iIncludePaths.push_back(FixPathString(toLower(tempStr))); |
|
257 properChild = true; |
|
258 } |
|
259 } |
|
260 else if( elemtypeStr == PLATFORM_ELEMENT_FORCEDINCLUDE ) |
|
261 { |
|
262 // Forced Include: |
|
263 const XMLCh* nodeVal = node->getTextContent(); |
|
264 if( nodeVal ) |
|
265 { |
|
266 iForcedInclude=toString(nodeVal); |
|
267 properChild = true; |
|
268 } |
|
269 } |
|
270 } |
|
271 return properChild; |
|
272 } |
|
273 |
|
274 /** |
|
275 * |
|
276 */ |
|
277 const vector<string>& ComponentFile::IncludePaths() const |
|
278 { |
|
279 return iIncludePaths; |
|
280 } |
|
281 |
|
282 /** |
|
283 * |
|
284 */ |
|
285 void ComponentFile::AddIncludePath(const string& incPath) |
|
286 { |
|
287 if( IsObjectInVector<string>(iIncludePaths, incPath) == false ) |
|
288 iIncludePaths.push_back(incPath); |
|
289 } |
|
290 |
|
291 const vector<string>& ComponentFile::Includes() const |
|
292 { |
|
293 return iIncludes; |
|
294 } |
|
295 |
|
296 void ComponentFile::AddInclude(const string& incHdr) |
|
297 { |
|
298 if( IsObjectInVector<string>(iIncludes, incHdr) == false ) |
|
299 iIncludes.push_back(incHdr); |
|
300 } |
|
301 |
|
302 void ComponentFile::SetIncludes(const vector<string>& incs) |
|
303 { |
|
304 iIncludes = incs; |
|
305 } |
|
306 |
|
307 ParsedElement::ParsedElement() |
|
308 {} |
|
309 |
|
310 ParsedElement::~ParsedElement() |
|
311 {} |
|
312 |
|
313 /** |
|
314 * Initializes the element using parsed XML (DOM) data. This method initiates |
|
315 * attribute processing, child element processing and adds the element to |
|
316 * the platform data object. |
|
317 */ |
|
318 bool ParsedElement::Initialize(DOMNode* node, PlatformData* platform) |
|
319 { |
|
320 if( node == 0 || platform == 0 ) |
|
321 return false; |
|
322 |
|
323 iRootDir = platform->GetRootDir(); |
|
324 |
|
325 // Read and process attributes of xml-element: |
|
326 ProcessAttributes(node); |
|
327 |
|
328 // Process child elements: |
|
329 DOMNodeList* childNodes = node->getChildNodes(); |
|
330 XMLSize_t childListLen = 0; |
|
331 if( childNodes ) |
|
332 { |
|
333 childListLen = childNodes->getLength(); |
|
334 for( XMLSize_t cI = 0; cI < childListLen; ++cI ) |
|
335 { |
|
336 DOMNode* childNode = childNodes->item(cI); |
|
337 if( childNode ) |
|
338 { |
|
339 ProcessChildElement(childNode, platform); |
|
340 } |
|
341 } |
|
342 } |
|
343 |
|
344 // Add this element to a proper container of the platform data object: |
|
345 return AddToPlatform(platform); |
|
346 } |
|
347 |
|
348 /** |
|
349 * |
|
350 */ |
|
351 Project::Project() |
|
352 {} |
|
353 |
|
354 /** |
|
355 * |
|
356 */ |
|
357 Project::Project(const string& prjID, Component* comp) |
|
358 : ComponentFile(prjID, comp) |
|
359 { } |
|
360 |
|
361 /** |
|
362 * |
|
363 */ |
|
364 Project::~Project() |
|
365 { } |
|
366 |
|
367 /** |
|
368 * Adds this project element to platform's project list. |
|
369 */ |
|
370 bool Project::AddToPlatform(PlatformData* platform) |
|
371 { |
|
372 return platform->AddProject(this); |
|
373 } |
|
374 |
|
375 /** |
|
376 * Processes the given child element. Project can have following |
|
377 * child elements: |
|
378 * - includepath |
|
379 * - source |
|
380 */ |
|
381 bool Project::ProcessChildElement(DOMNode* child, PlatformData* platform) |
|
382 { |
|
383 if( ComponentFile::ProcessChildElement(child, platform) == true ) |
|
384 return true; |
|
385 |
|
386 bool properChild = false; |
|
387 const XMLCh* childtype = child->getNodeName(); |
|
388 if( childtype ) |
|
389 { |
|
390 string childtypeStr(toString(childtype)); |
|
391 const XMLCh* nodeVal = child->getTextContent(); |
|
392 if( nodeVal ) |
|
393 { |
|
394 if( childtypeStr == PLATFORM_ELEMENT_SOURCE ) |
|
395 { |
|
396 Source* srcObj = new Source(); |
|
397 if( srcObj->Initialize(child, platform) ) |
|
398 { |
|
399 iSourceObjs.push_back(srcObj); |
|
400 properChild = true; |
|
401 } |
|
402 else |
|
403 delete srcObj; |
|
404 } |
|
405 } |
|
406 } |
|
407 return properChild; |
|
408 } |
|
409 |
|
410 /** |
|
411 * |
|
412 */ |
|
413 const FileList& Project::Sources() const |
|
414 { |
|
415 return iSourceObjs; |
|
416 } |
|
417 |
|
418 /** |
|
419 * |
|
420 */ |
|
421 string Project::PrettyPrint(int indentSpaces) const |
|
422 { |
|
423 string ret; |
|
424 for( int i = 0; i < indentSpaces; ++i ) |
|
425 { |
|
426 ret += " "; |
|
427 } |
|
428 ret += string("Project ID: ") + iID + "\n"; |
|
429 for( int i = 0; i < indentSpaces; ++i ) |
|
430 { |
|
431 ret += " "; |
|
432 } |
|
433 ret += "Sources:\n"; |
|
434 for( FileList::const_iterator s = iSourceObjs.begin(); s != iSourceObjs.end(); ++s ) |
|
435 { |
|
436 ret += (*s)->PrettyPrint(indentSpaces+2); |
|
437 } |
|
438 return ret; |
|
439 } |
|
440 |
|
441 /** |
|
442 * Header |
|
443 */ |
|
444 Header::Header() |
|
445 : |
|
446 iCachedIncludes(0), |
|
447 iCachedIncludePaths(0), |
|
448 iCachedForcedInclude("") |
|
449 {} |
|
450 /** |
|
451 * |
|
452 */ |
|
453 Header::Header(const string& hdrID, Component* comp) |
|
454 : |
|
455 ComponentFile(hdrID, comp), |
|
456 iCachedIncludes(0), |
|
457 iCachedIncludePaths(0), |
|
458 iCachedForcedInclude("") |
|
459 { } |
|
460 |
|
461 /** |
|
462 * |
|
463 */ |
|
464 Header::~Header() |
|
465 { |
|
466 delete iCachedIncludes; |
|
467 delete iCachedIncludePaths; |
|
468 } |
|
469 |
|
470 /** |
|
471 * |
|
472 */ |
|
473 Header::STATUS Header::Status() const |
|
474 { |
|
475 return iStatus; |
|
476 } |
|
477 |
|
478 /** |
|
479 * |
|
480 */ |
|
481 void Header::SetStatus(Header::STATUS s) |
|
482 { |
|
483 iStatus = s; |
|
484 } |
|
485 |
|
486 /** |
|
487 * |
|
488 */ |
|
489 bool Header::AddToPlatform(PlatformData* platform) |
|
490 { |
|
491 return platform->AddHeader(this); |
|
492 } |
|
493 |
|
494 /** |
|
495 * |
|
496 */ |
|
497 string Header::PrettyPrint(int indentSpaces) const |
|
498 { |
|
499 string ret; |
|
500 for( int i = 0; i < indentSpaces; ++i ) |
|
501 { |
|
502 ret += " "; |
|
503 } |
|
504 ret += string("Header ID: ") + iID + "\n"; |
|
505 |
|
506 return ret; |
|
507 } |
|
508 |
|
509 void Header::ProcessAttributes(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node) |
|
510 { |
|
511 /** |
|
512 * Header element uses absolute path as a key, since that way it is easier |
|
513 * to map this element to the filenames used in Analyser. Absolute path |
|
514 * is calculated merging the root directories given in parameters (i.e BASELINEDIR |
|
515 * and CURRENTDIR). |
|
516 */ |
|
517 const XMLCh* fileIdAttr = GetAttribute(node, XML_FILE_ID_ATTRIBUTE); |
|
518 if( fileIdAttr ) |
|
519 { |
|
520 string tempStr(toString(fileIdAttr)); |
|
521 FixPathString(toLower(tempStr)); |
|
522 // Merge root and element directories. |
|
523 // START -- Support for multiple header directories -- |
|
524 list<pair<string, bool> > fullID = BBCFileUtils::MergeDirs(iRootDir, tempStr); |
|
525 list<pair<string, bool> >::iterator fulliterbegin = fullID.begin(); |
|
526 for(; fulliterbegin != fullID.end(); fulliterbegin++) |
|
527 { |
|
528 if( fulliterbegin->second ) |
|
529 { |
|
530 iID = fulliterbegin->first; |
|
531 } |
|
532 } |
|
533 // END -- Support for multiple header directories -- |
|
534 } |
|
535 } |
|
536 |
|
537 /** |
|
538 * When IncludesForHeader() method of PlatformData is called, PlatformData |
|
539 * retrieves the additional include directives from all the sources in the |
|
540 * component and caches the include directives to Header object, so next |
|
541 * time the retrival is faster. |
|
542 */ |
|
543 |
|
544 /** |
|
545 * |
|
546 */ |
|
547 const vector<string>* Header::CachedIncludes() const |
|
548 { |
|
549 return iCachedIncludes; |
|
550 } |
|
551 |
|
552 /** |
|
553 * |
|
554 */ |
|
555 void Header::SetCachedIncludes(vector<string>* incs) |
|
556 { |
|
557 if( iCachedIncludes ) |
|
558 delete iCachedIncludes; |
|
559 iCachedIncludes = incs; |
|
560 } |
|
561 |
|
562 /** |
|
563 * When IncludesPathsForHeader() method of PlatformData is called, PlatformData |
|
564 * retrieves the include paths from all the projects in the component and |
|
565 * caches the include paths to Header object, so next time the retrival is |
|
566 * faster. |
|
567 */ |
|
568 |
|
569 /** |
|
570 * |
|
571 */ |
|
572 const vector<string>* Header::CachedIncludePaths() const |
|
573 { |
|
574 return iCachedIncludePaths; |
|
575 } |
|
576 |
|
577 /** |
|
578 * |
|
579 */ |
|
580 void Header::SetCachedIncludePaths(vector<string>* incPaths) |
|
581 { |
|
582 if( iCachedIncludePaths ) |
|
583 delete iCachedIncludePaths; |
|
584 iCachedIncludePaths = incPaths; |
|
585 } |
|
586 |
|
587 |
|
588 /** |
|
589 * When IncludesForHeader() method of PlatformData is called, PlatformData |
|
590 * retrieves the additional forced include directive from the component |
|
591 * and caches the forced include directive to Header object, so next |
|
592 * time the retrival is faster. |
|
593 */ |
|
594 |
|
595 /** |
|
596 * |
|
597 */ |
|
598 string Header::CachedForcedInclude() const |
|
599 { |
|
600 return iCachedForcedInclude; |
|
601 } |
|
602 |
|
603 string Header::CachedSource() const |
|
604 { |
|
605 return iCacheSrcObj; |
|
606 } |
|
607 |
|
608 /** |
|
609 * |
|
610 */ |
|
611 void Header::SetCachedForcedInclude(string finc) |
|
612 { |
|
613 iCachedForcedInclude = finc; |
|
614 } |
|
615 |
|
616 void Header::SetCachedSourceFile (string srcObj) |
|
617 { |
|
618 iCacheSrcObj = srcObj; |
|
619 } |
|
620 /** |
|
621 * Source |
|
622 */ |
|
623 Source::Source() |
|
624 {} |
|
625 |
|
626 /** |
|
627 * |
|
628 */ |
|
629 Source::Source(const string& srcID, Component* comp) |
|
630 : ComponentFile(srcID, comp) |
|
631 { } |
|
632 |
|
633 /** |
|
634 * |
|
635 */ |
|
636 Source::~Source() |
|
637 { } |
|
638 |
|
639 /** |
|
640 * |
|
641 */ |
|
642 bool Source::AddToPlatform(PlatformData* platform) |
|
643 { |
|
644 return platform->AddSource(this); |
|
645 } |
|
646 |
|
647 /** |
|
648 * |
|
649 */ |
|
650 string Source::PrettyPrint(int indentSpaces) const |
|
651 { |
|
652 string ret; |
|
653 for( int i = 0; i < indentSpaces; ++i ) |
|
654 { |
|
655 ret += " "; |
|
656 } |
|
657 ret += string("Source ID: ") + iID + "\n"; |
|
658 for( int i = 0; i < indentSpaces; ++i ) |
|
659 { |
|
660 ret += " "; |
|
661 } |
|
662 ret += "Include directives:\n"; |
|
663 for( vector<string>::const_iterator inc = iIncludes.begin(); inc != iIncludes.end(); ++inc ) |
|
664 { |
|
665 for( int i = 0; i < indentSpaces+2; ++i ) |
|
666 { |
|
667 ret += " "; |
|
668 } |
|
669 ret += *inc + "\n"; |
|
670 } |
|
671 |
|
672 return ret; |
|
673 } |
|
674 |
|
675 /** |
|
676 * Component |
|
677 */ |
|
678 Component::Component() |
|
679 { } |
|
680 |
|
681 /** |
|
682 * |
|
683 */ |
|
684 Component::Component(const string& compID, Component* comp) |
|
685 : |
|
686 ComponentFile(compID, comp) |
|
687 { } |
|
688 |
|
689 /** |
|
690 * |
|
691 */ |
|
692 Component::~Component() |
|
693 { } |
|
694 |
|
695 /** |
|
696 * |
|
697 */ |
|
698 const FileList& Component::Headers() const |
|
699 { |
|
700 return iHeaders; |
|
701 } |
|
702 |
|
703 /** |
|
704 * |
|
705 */ |
|
706 FileList& Component::Headers() |
|
707 { |
|
708 return iHeaders; |
|
709 } |
|
710 |
|
711 /** |
|
712 * |
|
713 */ |
|
714 const FileList& Component::Projects() const |
|
715 { |
|
716 return iProjects; |
|
717 } |
|
718 |
|
719 /** |
|
720 * |
|
721 */ |
|
722 FileList& Component::Projects() |
|
723 { |
|
724 return iProjects; |
|
725 } |
|
726 |
|
727 /** |
|
728 * |
|
729 */ |
|
730 void Component::AddHeader(ComponentFile* hdr) |
|
731 { |
|
732 if( IsObjectInVector<ComponentFile*>(iHeaders, hdr) == false ) |
|
733 { |
|
734 iHeaders.push_back(hdr); |
|
735 } |
|
736 } |
|
737 |
|
738 /** |
|
739 * |
|
740 */ |
|
741 void Component::AddProject(ComponentFile* prj) |
|
742 { |
|
743 if( IsObjectInVector<ComponentFile*>(iProjects, prj) == false ) |
|
744 { |
|
745 iProjects.push_back(prj); |
|
746 } |
|
747 } |
|
748 |
|
749 /** |
|
750 * Processes child elements. Component can have following child elements: |
|
751 * - Header |
|
752 * - Project reference |
|
753 */ |
|
754 bool Component::ProcessChildElement(DOMNode* child, PlatformData* platform) |
|
755 { |
|
756 if( ComponentFile::ProcessChildElement(child, platform) == true ) |
|
757 return true; |
|
758 |
|
759 bool properChild = false; |
|
760 const XMLCh* childtype = child->getNodeName(); |
|
761 if( childtype ) |
|
762 { |
|
763 string childtypeStr(toString(childtype)); |
|
764 if( childtypeStr == PLATFORM_ELEMENT_HEADER ) |
|
765 { |
|
766 Header* hdr = new Header(); |
|
767 string headerID(this->ID()); |
|
768 if( hdr->Initialize(child, platform) ) |
|
769 { |
|
770 if(headerID == PLATFORM_IGNORED_COMPONENT ) |
|
771 hdr->SetStatus(Header::HDR_STATUS_IGNORE); |
|
772 |
|
773 XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* hdrNode = (DOMElement*)child; |
|
774 char* headername = _X( hdrNode->getAttribute( _X( "id" ) ) ); |
|
775 string header (headername); |
|
776 header = FixPathString(toLower(header)); |
|
777 int loc = header.find_last_of(DIR_SEPARATOR); |
|
778 if(loc != -1 ) |
|
779 { |
|
780 // store header file name and path from header id tag only. |
|
781 hdr->SetFileName(header.substr(loc+1,string::npos)); |
|
782 hdr->SetPath(header.substr(0,loc)); |
|
783 } |
|
784 _XX(headername); |
|
785 |
|
786 hdr->SetComponent(this); |
|
787 iHeaders.push_back(hdr); |
|
788 properChild = true; |
|
789 } |
|
790 else |
|
791 { |
|
792 delete hdr; |
|
793 } |
|
794 } |
|
795 else if( childtypeStr == PLATFORM_ELEMENT_PROJECT ) |
|
796 { |
|
797 Project* prj = new Project(); |
|
798 if (prj->Initialize(child, platform) ) |
|
799 { |
|
800 prj->SetComponent(this); |
|
801 iProjects.push_back(prj); |
|
802 properChild = true; |
|
803 } |
|
804 else |
|
805 { |
|
806 delete prj; |
|
807 } |
|
808 } |
|
809 } |
|
810 return properChild; |
|
811 } |
|
812 |
|
813 /** |
|
814 * |
|
815 */ |
|
816 bool Component::AddToPlatform(PlatformData* platform) |
|
817 { |
|
818 return platform->AddComponent(this); |
|
819 } |
|
820 |
|
821 /** |
|
822 * |
|
823 */ |
|
824 string Component::PrettyPrint(int indentSpaces) const |
|
825 { |
|
826 string ret; |
|
827 for( int i = 0; i < indentSpaces; ++i ) |
|
828 { |
|
829 ret += " "; |
|
830 } |
|
831 ret += string("Component ID: ") + iID + "\n"; |
|
832 for( int i = 0; i < indentSpaces; ++i ) |
|
833 { |
|
834 ret += " "; |
|
835 } |
|
836 ret += "Headers:\n"; |
|
837 for( FileList::const_iterator h = iHeaders.begin(); h != iHeaders.end(); ++h ) |
|
838 { |
|
839 ret += (*h)->PrettyPrint(indentSpaces+2); |
|
840 } |
|
841 |
|
842 for( int i = 0; i < indentSpaces; ++i ) |
|
843 { |
|
844 ret += " "; |
|
845 } |
|
846 ret += "Projects\n"; |
|
847 |
|
848 for( FileList::const_iterator p = iProjects.begin(); p != iProjects.end(); ++p ) |
|
849 { |
|
850 ret += (*p)->PrettyPrint(indentSpaces+2); |
|
851 } |
|
852 |
|
853 return ret; |
|
854 } |
|
855 |
|
856 /** |
|
857 * PlatformData contains all the elements defined in the platrofm input file. |
|
858 * It parses the XML-file and populates the internal containers. It also |
|
859 * has different kind of methods for retrieving the data and the associations |
|
860 * between elements. |
|
861 */ |
|
862 PlatformData::PlatformData(const string& pfVersion, const string& rootDir) |
|
863 : |
|
864 iDOMParser(0), |
|
865 iDOMDoc(0), |
|
866 iDOMRootElement(0), |
|
867 iPfVersion(pfVersion), |
|
868 iRootDir(rootDir) |
|
869 { } |
|
870 |
|
871 /** |
|
872 * |
|
873 */ |
|
874 PlatformData::~PlatformData() |
|
875 { |
|
876 if (iDOMParser != NULL) |
|
877 { |
|
878 iDOMParser->resetDocumentPool(); |
|
879 iDOMParser->release(); |
|
880 iDOMParser = NULL; |
|
881 } |
|
882 |
|
883 CFileMap::iterator i; |
|
884 |
|
885 for( i = iHeadersById.begin(); i != iHeadersById.end(); ++i ) |
|
886 { |
|
887 delete i->second; |
|
888 } |
|
889 |
|
890 for( i = iProjectsById.begin(); i != iProjectsById.end(); ++i ) |
|
891 { |
|
892 delete i->second; |
|
893 } |
|
894 |
|
895 for( i = iSourcesById.begin(); i != iSourcesById.end(); ++i ) |
|
896 { |
|
897 delete i->second; |
|
898 } |
|
899 |
|
900 for( ComponentList::iterator ic = iCList.begin(); ic != iCList.end(); ++ic ) |
|
901 { |
|
902 delete ic->second; |
|
903 } |
|
904 } |
|
905 |
|
906 /** |
|
907 * |
|
908 */ |
|
909 void PlatformData::Initialize(const string& dataFileName) |
|
910 { |
|
911 // First read and parse the XML-file: |
|
912 int ret = 0; |
|
913 if (iDOMParser != NULL) |
|
914 { |
|
915 iDOMParser->resetDocumentPool(); |
|
916 iDOMParser->release(); |
|
917 iDOMParser = 0; |
|
918 } |
|
919 cout << "Parsing platform data for " << iPfVersion << "..."; |
|
920 try { |
|
921 ret = ParseXMLFile(dataFileName, iDOMParser, iDOMDoc, iDOMRootElement); |
|
922 } |
|
923 catch (HAException&) |
|
924 { |
|
925 cout.flush(); |
|
926 cerr.flush(); |
|
927 cerr << "Failed!" << endl; |
|
928 if( iDOMParser ) |
|
929 { |
|
930 iDOMParser->resetDocumentPool(); |
|
931 iDOMParser->release(); |
|
932 iDOMParser = 0; |
|
933 } |
|
934 throw; |
|
935 } |
|
936 cout << "Done." << endl; |
|
937 |
|
938 // Then traverse the DOM tree and populate the containers: |
|
939 cout << "Initializing platform data for " << iPfVersion << "..."; |
|
940 try { |
|
941 InitializeElements(); |
|
942 } |
|
943 catch( HAException& ) |
|
944 { |
|
945 cerr << "Failed." << endl; |
|
946 iDOMParser->resetDocumentPool(); |
|
947 iDOMParser->release(); |
|
948 iDOMParser = 0; |
|
949 throw; |
|
950 } |
|
951 cout << "Done." << endl; |
|
952 iDOMParser->resetDocumentPool(); |
|
953 iDOMParser->release(); |
|
954 iDOMParser = 0; |
|
955 cout << "Platform " << iPfVersion << " successfully initialized from platform " << iVersionStr << " data!" << endl << endl; |
|
956 } |
|
957 |
|
958 /** |
|
959 * |
|
960 */ |
|
961 bool PlatformData::AddComponent(Component* comp) |
|
962 { |
|
963 return iCList.insert(make_pair<string, Component*>( comp->ID(), comp )).second; |
|
964 } |
|
965 |
|
966 /** |
|
967 * |
|
968 */ |
|
969 bool PlatformData::AddProject(Project* prj) |
|
970 { |
|
971 if( iProjectsById.insert(make_pair<string, ComponentFile*>(prj->ID(), prj)).second == false ) |
|
972 return false; |
|
973 |
|
974 return true; |
|
975 } |
|
976 |
|
977 /** |
|
978 * |
|
979 */ |
|
980 bool PlatformData::AddSource(Source* src) |
|
981 { |
|
982 if( iSourcesById.insert(make_pair<string, ComponentFile*>(src->ID(), src)).second == false ) |
|
983 return false; |
|
984 |
|
985 return true; |
|
986 } |
|
987 |
|
988 /** |
|
989 * |
|
990 */ |
|
991 bool PlatformData::AddHeader(Header* hdr) |
|
992 { |
|
993 if( iHeadersById.insert(make_pair<string, ComponentFile*>(hdr->ID(), hdr)).second == false ) |
|
994 return false; |
|
995 |
|
996 return true; |
|
997 } |
|
998 |
|
999 /** |
|
1000 * Factory method for creating element objects. |
|
1001 */ |
|
1002 ParsedElement* PlatformData::CreateElement( XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node ) |
|
1003 { |
|
1004 const string elementType( toString( node->getNodeName() )); |
|
1005 ParsedElement* elem = 0; |
|
1006 |
|
1007 if( elementType == PLATFORM_ELEMENT_COMPONENT ) |
|
1008 { |
|
1009 elem = new Component(); |
|
1010 } |
|
1011 else if( elementType == PLATFORM_ELEMENT_PROJECT ) |
|
1012 { |
|
1013 elem = new Project(); |
|
1014 } |
|
1015 else if( elementType == PLATFORM_ELEMENT_SOURCE ) |
|
1016 { |
|
1017 elem = new Source(); |
|
1018 } |
|
1019 |
|
1020 return elem; |
|
1021 } |
|
1022 |
|
1023 /** |
|
1024 * Traverses through the DOM-tree and builds element objects. |
|
1025 */ |
|
1026 void PlatformData::InitializeElements() |
|
1027 { |
|
1028 if( iDOMDoc == 0 || iDOMRootElement == 0) |
|
1029 throw HAException(string("Platform ") + string(iPfVersion) + string(" initialization failed.\n")); |
|
1030 DOMNodeIterator* domIter = iDOMDoc->createNodeIterator(iDOMRootElement, DOMNodeFilter::SHOW_ELEMENT, NULL, true); |
|
1031 if( domIter == 0 ) |
|
1032 throw HAException(string("Platform ") + string(iPfVersion) + string(" initialization failed.\n")); |
|
1033 DOMNode* root = domIter->getRoot(); |
|
1034 if( root ) |
|
1035 { |
|
1036 const XMLCh* platformVersion = GetAttribute(root, KXMLPlatformVersion); |
|
1037 if( platformVersion ) |
|
1038 iVersionStr = toString(platformVersion); |
|
1039 } |
|
1040 DOMNode* nodeIter = 0; |
|
1041 ParsedElement* elem = 0; |
|
1042 while( (nodeIter = domIter->nextNode()) != 0 ) |
|
1043 { |
|
1044 elem = CreateElement(nodeIter); |
|
1045 if( elem && elem->Initialize(nodeIter, this) == false ) |
|
1046 { |
|
1047 delete elem; |
|
1048 } |
|
1049 } |
|
1050 |
|
1051 domIter->release(); |
|
1052 } |
|
1053 |
|
1054 /** |
|
1055 * |
|
1056 */ |
|
1057 const CFileMap& PlatformData::HeadersById() const |
|
1058 { |
|
1059 return iHeadersById; |
|
1060 } |
|
1061 |
|
1062 /** |
|
1063 * |
|
1064 */ |
|
1065 const CFileMap& PlatformData::ProjectsById() const |
|
1066 { |
|
1067 return iProjectsById; |
|
1068 } |
|
1069 |
|
1070 /** |
|
1071 * |
|
1072 */ |
|
1073 CFileMap& PlatformData::ProjectsById() |
|
1074 { |
|
1075 return iProjectsById; |
|
1076 } |
|
1077 |
|
1078 /** |
|
1079 * |
|
1080 */ |
|
1081 const CFileMap& PlatformData::SourcesById() const |
|
1082 { |
|
1083 return iSourcesById; |
|
1084 } |
|
1085 |
|
1086 /** |
|
1087 * Finds include paths defined in the projects belonging to the |
|
1088 * same component than the header. |
|
1089 */ |
|
1090 const vector<string>& PlatformData::IncludePathsForHeader(const string& headerID) |
|
1091 { |
|
1092 CFileMap::const_iterator hdrIter = iHeadersById.find(headerID); |
|
1093 if( hdrIter != iHeadersById.end() ) |
|
1094 { |
|
1095 Header* hdrObj = dynamic_cast<Header*>(hdrIter->second); |
|
1096 if( hdrObj ) |
|
1097 return IncludePathsForHeader(hdrObj); |
|
1098 } |
|
1099 |
|
1100 return iDummyStringVector; |
|
1101 } |
|
1102 |
|
1103 /** |
|
1104 * Finds include paths defined in the projects belonging to the |
|
1105 * same component than the header. |
|
1106 */ |
|
1107 const vector<string>& PlatformData::IncludePathsForHeader(Header* hdrObj) |
|
1108 { |
|
1109 if( hdrObj == 0 ) |
|
1110 return iDummyStringVector; |
|
1111 |
|
1112 // First try to find includes from the cache: |
|
1113 const vector<string>* cached = hdrObj->CachedIncludePaths(); |
|
1114 if( cached ) |
|
1115 { |
|
1116 return *cached; |
|
1117 } |
|
1118 |
|
1119 auto_ptr<vector<string> > newVector(new vector<string>()); |
|
1120 Component* comp = 0; |
|
1121 |
|
1122 if( (comp = hdrObj->GetComponent()) != 0 ) |
|
1123 { |
|
1124 // First insert the include paths defined in component level: |
|
1125 newVector->insert(newVector->end(), comp->IncludePaths().begin(), comp->IncludePaths().end()); |
|
1126 |
|
1127 const FileList& prjs = comp->Projects(); |
|
1128 for( FileList::const_iterator prj = prjs.begin(); prj != prjs.end(); ++prj ) |
|
1129 { |
|
1130 Project* prjObj = dynamic_cast<Project*>(*prj); |
|
1131 if( prjObj ) |
|
1132 { |
|
1133 const vector<string>& iPaths = prjObj->IncludePaths(); |
|
1134 vector<string>::const_iterator ip = iPaths.begin(); |
|
1135 |
|
1136 for( ; ip != iPaths.end(); ++ip ) |
|
1137 { |
|
1138 if( !IsObjectInVector(*newVector, *ip) ) |
|
1139 { |
|
1140 newVector->push_back(*ip); |
|
1141 } |
|
1142 } |
|
1143 } |
|
1144 } |
|
1145 } |
|
1146 |
|
1147 const vector<string>& hdrIncs = hdrObj->IncludePaths(); |
|
1148 for( vector<string>::const_iterator i = hdrIncs.begin(); i != hdrIncs.end(); ++i ) |
|
1149 { |
|
1150 if( !IsObjectInVector(*newVector, *i) ) |
|
1151 { |
|
1152 newVector->push_back(*i); |
|
1153 } |
|
1154 } |
|
1155 |
|
1156 // variable to track whether project has been found |
|
1157 bool found = false; |
|
1158 // Find a project in the platform data which includes the header under analysis and |
|
1159 // add all paths in the mmp file as dependencies before compilation. |
|
1160 for( CFileMap::const_iterator pIter = iProjectsById.begin(); pIter != iProjectsById.end() && !found; ++pIter ) |
|
1161 { |
|
1162 //First iterate over projects |
|
1163 Project* prj = dynamic_cast<Project*>(pIter->second); |
|
1164 const FileList& src = prj->Sources(); |
|
1165 FileList::const_iterator sIter = src.begin(); |
|
1166 for(;sIter != src.end() && !found; ++sIter) |
|
1167 { |
|
1168 // then search each source include in individual projects |
|
1169 Source* so = dynamic_cast<Source*>(*sIter); |
|
1170 const vector<string>& inc = so->Includes(); |
|
1171 vector<string>::const_iterator iIter = inc.begin(); |
|
1172 for(;iIter != inc.end() && !found; ++iIter) |
|
1173 { |
|
1174 string::size_type dirEnd = (*iIter).find_last_of('/\\'); |
|
1175 // IF header found |
|
1176 if( (dirEnd == string::npos && *iIter == hdrObj->FileName()) || |
|
1177 (dirEnd != string::npos && string((*iIter).begin()+dirEnd+1, (*iIter).end()) == hdrObj->FileName())) |
|
1178 { |
|
1179 const vector<string>& tmp = prj->IncludePaths(); |
|
1180 if( IsObjectInVector<string>(tmp, hdrObj->Path()) ) |
|
1181 { |
|
1182 vector<string>::const_iterator str = tmp.begin(); |
|
1183 for(;str != prj->IncludePaths().end(); ++str) |
|
1184 { |
|
1185 // only include paths which are not already present |
|
1186 if( !IsObjectInVector<string>(*newVector, *str) ) |
|
1187 { |
|
1188 newVector->insert(newVector->end(), *str); |
|
1189 found = true; |
|
1190 } |
|
1191 } |
|
1192 } |
|
1193 } |
|
1194 } |
|
1195 } |
|
1196 } |
|
1197 hdrObj->SetCachedIncludePaths(newVector.release()); |
|
1198 return *(hdrObj->CachedIncludePaths()); |
|
1199 } |
|
1200 |
|
1201 /** |
|
1202 * Finds include directives used with this header when the header |
|
1203 * is compiled. Algorithm finds the <code>Header</code> object using |
|
1204 * the given ID and then calls overloaded <code>IncludesForHeader</code> |
|
1205 * using the <code>Header</code> object. |
|
1206 */ |
|
1207 const vector<string>& PlatformData::IncludesForHeader( const string& headerID ) |
|
1208 { |
|
1209 CFileMap::const_iterator hdrIter = iHeadersById.find(headerID); |
|
1210 if( hdrIter != iHeadersById.end() ) |
|
1211 { |
|
1212 Header* hObj = dynamic_cast<Header*>(hdrIter->second); |
|
1213 if( hObj ) |
|
1214 return IncludesForHeader(hObj); |
|
1215 } |
|
1216 return iDummyStringVector; |
|
1217 } |
|
1218 |
|
1219 void PlatformData::IncludesFromSource(const Header* hObj, const Source* srcObj, vector<string>& includes) const |
|
1220 { |
|
1221 const vector<string>& includeDirectives = srcObj->Includes(); |
|
1222 vector<string>::const_iterator inc = includeDirectives.begin(); |
|
1223 for( ; inc != includeDirectives.end(); ++inc ) |
|
1224 { |
|
1225 string::size_type dirEnd = (*inc).find_last_of("/\\"); |
|
1226 |
|
1227 if( (dirEnd == string::npos && *inc == hObj->FileName()) || |
|
1228 (dirEnd != string::npos && string(inc->begin()+dirEnd+1, inc->end()) == hObj->FileName())) |
|
1229 { |
|
1230 // The header was found. Take all the preceding include directives: |
|
1231 for( vector<string>::const_iterator tempIt = includeDirectives.begin(); tempIt != inc; ++tempIt) |
|
1232 { |
|
1233 if( IsObjectInVector(includes, *tempIt) == false ) |
|
1234 { |
|
1235 includes.push_back(*tempIt); |
|
1236 } |
|
1237 } |
|
1238 break; |
|
1239 } |
|
1240 } |
|
1241 } |
|
1242 |
|
1243 /** |
|
1244 * Finds include directives used with this header when the header |
|
1245 * is compiled. Algorithm find first all the projects belonging |
|
1246 * to the same component than the given <code>Header</code> object. |
|
1247 * Then it finds all the source files belonging to the projects. |
|
1248 * Then it scans the source files and if a source file includes |
|
1249 * this header, all the preceding include directives in that source |
|
1250 * file are inserted to the result vector. |
|
1251 * |
|
1252 * An example: |
|
1253 * |
|
1254 * Header, id: epoc32/include/hdr1.h, belongs to component c, which |
|
1255 * contains one project p.mmp. Project p.mmp contains two source files: |
|
1256 * s1.cpp and s2.cpp. Source s1.cpp includes hdrX.h, hdrY.h and hdr1.h |
|
1257 * (in that order). Source s2.cpp does not include the hdr1.h at all. |
|
1258 * The returned headers in above example would be hdrX.h and hdrY.h. |
|
1259 */ |
|
1260 const vector<string>& PlatformData::IncludesForHeader(Header* hObj, Header* baseHObj) |
|
1261 { |
|
1262 string tempSpurceObj; |
|
1263 if( hObj == 0 ) |
|
1264 return iDummyStringVector; |
|
1265 |
|
1266 if( hObj->CachedIncludes() != 0 ) |
|
1267 return *(hObj->CachedIncludes()); |
|
1268 |
|
1269 |
|
1270 // Start build new include list: |
|
1271 auto_ptr<vector<string> > newVector(new vector<string>()); |
|
1272 Component* comp = 0; |
|
1273 |
|
1274 if( (comp = hObj->GetComponent()) != 0 ) |
|
1275 { |
|
1276 //set the forced header for this header |
|
1277 hObj->SetCachedForcedInclude(comp->ForcedInclude()); |
|
1278 // Insert include directives defined in component level: |
|
1279 newVector->insert(newVector->end(), comp->Includes().begin(), comp->Includes().end()); |
|
1280 |
|
1281 // Then find all the sources that are including this header and get all the preceding include |
|
1282 // directives from the sources. The shortest list will do. |
|
1283 |
|
1284 const FileList& projects = comp->Projects(); // All the projects in this component |
|
1285 FileList::const_iterator fIter = projects.begin(); |
|
1286 |
|
1287 // Get needed source files from the projects of this component: |
|
1288 FileList srcObjs; |
|
1289 for( ; fIter != projects.end(); ++fIter ) |
|
1290 { |
|
1291 Project* prj = dynamic_cast<Project*>(*fIter); |
|
1292 if( prj ) |
|
1293 { |
|
1294 srcObjs.insert(srcObjs.end(), prj->Sources().begin(), prj->Sources().end()); |
|
1295 } |
|
1296 } |
|
1297 |
|
1298 // Next we investigate the include directives of each source file |
|
1299 // and get all the headers that are included before the given |
|
1300 // header file. |
|
1301 auto_ptr<vector<string> > includesFromSrc(0); |
|
1302 for( FileList::iterator src = srcObjs.begin(); src != srcObjs.end(); ++src ) |
|
1303 { |
|
1304 Source* srcObj = dynamic_cast<Source*>(*src); |
|
1305 if( srcObj == 0 ) |
|
1306 continue; |
|
1307 |
|
1308 const vector<string>& includeDirectives = srcObj->Includes(); |
|
1309 vector<string>::const_iterator inc = includeDirectives.begin(); |
|
1310 auto_ptr<vector<string> > tmpIncludes(new vector<string>()); |
|
1311 |
|
1312 IncludesFromSource(hObj, srcObj, *tmpIncludes); |
|
1313 if( includesFromSrc.get() == 0 || |
|
1314 (tmpIncludes->size() > 0 && (tmpIncludes->size() < includesFromSrc->size() || includesFromSrc->size()==0) )) |
|
1315 { |
|
1316 tempSpurceObj = srcObj->ID(); |
|
1317 includesFromSrc = tmpIncludes; // Get the smallest possible set of additional includes. |
|
1318 } |
|
1319 } |
|
1320 if( includesFromSrc.get() ) |
|
1321 { |
|
1322 newVector->insert(newVector->end(), includesFromSrc->begin(), includesFromSrc->end()); |
|
1323 } |
|
1324 } |
|
1325 |
|
1326 if( newVector->size() == 0 ) |
|
1327 { |
|
1328 // No includes found. Let's try to find some source from other components. First one will do... |
|
1329 for( CFileMap::const_iterator s = iSourcesById.begin(); s != iSourcesById.end(); ++s ) |
|
1330 { |
|
1331 auto_ptr<vector<string> > tmpIncludes(new vector<string>()); |
|
1332 Source* sO = dynamic_cast<Source*>(s->second); |
|
1333 if( sO ) |
|
1334 { |
|
1335 IncludesFromSource(hObj, sO, *tmpIncludes); |
|
1336 if( tmpIncludes->size() > 0 ) |
|
1337 { |
|
1338 string curSrc; |
|
1339 string baseSrc; |
|
1340 if ( baseHObj != NULL) // IncludesForHeader() is called for current sdk |
|
1341 { |
|
1342 string::size_type loc = sO->ID().find_last_of('/\\'); |
|
1343 if(loc != string::npos ) |
|
1344 curSrc = sO->ID().substr(loc+1 , string::npos); |
|
1345 loc = string::npos; |
|
1346 loc = baseHObj->CachedSource().find_last_of('/\\'); |
|
1347 if(loc != string::npos) |
|
1348 baseSrc = baseHObj->CachedSource().substr(loc+1, string::npos); |
|
1349 } |
|
1350 // If the header is of baseline sdk or the current headers source file name is same as baseline's source file, |
|
1351 // In both of these cases , the dependent headers will be taken from platform data file |
|
1352 if(baseHObj == NULL || (baseSrc.size() > 0 && baseSrc == curSrc) ) |
|
1353 { |
|
1354 newVector->insert(newVector->end(), tmpIncludes->begin(), tmpIncludes->end()); |
|
1355 } |
|
1356 else // as current header's source file is not same as basiline's, so baseline's cacheinclude will be taken for current header too. |
|
1357 { |
|
1358 newVector->insert(newVector->end(), baseHObj->CachedIncludes()->begin(), baseHObj->CachedIncludes()->end()); |
|
1359 } |
|
1360 break; |
|
1361 } |
|
1362 } |
|
1363 } |
|
1364 } |
|
1365 hObj->SetCachedIncludes(newVector.release()); |
|
1366 if(baseHObj == NULL) // IncludesForHeader() is called for baseline sdk, so get the source file name in cache |
|
1367 { |
|
1368 hObj->SetCachedSourceFile(tempSpurceObj); |
|
1369 } |
|
1370 return *(hObj->CachedIncludes()); |
|
1371 } |
|
1372 /** |
|
1373 * |
|
1374 */ |
|
1375 string PlatformData::PrettyPrint() const |
|
1376 { |
|
1377 string ret("PLATFORM version: "); |
|
1378 ret += iVersionStr + "\n"; |
|
1379 |
|
1380 for( ComponentList::const_iterator c = iCList.begin(); c != iCList.end(); ++c ) |
|
1381 { |
|
1382 ret += c->second->PrettyPrint(); |
|
1383 } |
|
1384 return ret; |
|
1385 } |
|
1386 |
|
1387 /** |
|
1388 * |
|
1389 */ |
|
1390 const ComponentList& PlatformData::Components() const |
|
1391 { |
|
1392 return iCList; |
|
1393 } |
|
1394 |
|
1395 /** |
|
1396 * |
|
1397 */ |
|
1398 const string& PlatformData::GetRootDir() const |
|
1399 { |
|
1400 return iRootDir; |
|
1401 } |