apicompatanamdw/compatanalysercmd/headeranalyser/src/PlatformData.cpp
changeset 0 638b9c697799
equal deleted inserted replaced
-1:000000000000 0:638b9c697799
       
     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 }