perfsrv/analyzetool/commandlineengine/src/CATDatParser.cpp
changeset 48 516af714ebb4
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Class responsible to parse data files
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "../inc/CATDatParser.h"
       
    20 #include "../inc/CATProject.h"
       
    21 #include "../inc/CATModule2.h"
       
    22 #include "../inc/CATMemoryAddress.h"
       
    23 #include "../inc/catromsymbol.h"
       
    24 
       
    25 // -----------------------------------------------------------------------------
       
    26 // CATDatParser::CATDatParser
       
    27 // Constructor only for testing!
       
    28 // (No module vector defined so no locating codelines / call stacks)
       
    29 // -----------------------------------------------------------------------------
       
    30 CATDatParser::CATDatParser()
       
    31 {
       
    32 	LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
       
    33 	Construct();
       
    34 }
       
    35 
       
    36 // -----------------------------------------------------------------------------
       
    37 // CATDatParser::CATDatParser
       
    38 // Constructor
       
    39 // -----------------------------------------------------------------------------
       
    40 CATDatParser::CATDatParser(vector<CATModule2*>* pModules )
       
    41 {
       
    42 	LOG_FUNC_ENTRY("CATDatParser::CATDatParser");
       
    43 	Construct();
       
    44 	m_pModules = pModules;
       
    45 }
       
    46 
       
    47 // -----------------------------------------------------------------------------
       
    48 // CATDatParser::Construct
       
    49 // "Real" constructor
       
    50 // -----------------------------------------------------------------------------
       
    51 void CATDatParser::Construct()
       
    52 {
       
    53 	LOG_FUNC_ENTRY("CATDatParser::Construct");
       
    54 
       
    55 	m_iDataVersion = 1; // Default version of data.
       
    56 	m_bDllLoadFound = false;
       
    57 	m_bProcessStartFound = false;
       
    58 	m_bSubtestOnGoing = false;
       
    59 
       
    60 	m_DataSaver.InitXML();
       
    61 	
       
    62 	m_eBuildType = -2;
       
    63 	m_eProcess_state = not_started;
       
    64 	m_eProjectBuildType = -1;
       
    65 
       
    66 	m_iCurrentProcessId = 0;
       
    67 	m_iLeakNumber = 0;
       
    68 	m_iLogLevel = 3;
       
    69 	m_iOffSet = 0;
       
    70 
       
    71 	m_iPinPointedLeaks = 0;
       
    72 	m_iPinPointedSubTestLeaks = 0;
       
    73 	m_iSubtestStartHandleCount = 0;
       
    74 	m_iSuccesfullRuns = 0;
       
    75 	m_iTotalNumberOfLeaks = 0;
       
    76 	m_iTotalRuns = 0;
       
    77 
       
    78 	m_pRomSymbol = 0;
       
    79 	m_pModules = 0;
       
    80 
       
    81 	m_sCurrentProcessName = "";
       
    82 	m_sInputFile = "";
       
    83 	m_sInputFileTemp = "";
       
    84 	m_sOutputFile = "";
       
    85 	m_sProjectPlatform = "";
       
    86 	m_vRomSymbolFiles.clear();
       
    87 	m_vDllLoadModList.clear();
       
    88 	m_vDllLoadModListSubTest.clear();
       
    89 	m_vHandleLeaks.clear();
       
    90 	m_vMemoryAddress.clear();
       
    91 }
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CATDatParser::~CATDatParser
       
    95 // Destructor
       
    96 // -----------------------------------------------------------------------------
       
    97 CATDatParser::~CATDatParser()
       
    98 {
       
    99 	LOG_FUNC_ENTRY("CATDatParser::~CATDatParser");
       
   100 
       
   101 	if ( m_In.is_open() )
       
   102 		m_In.close();
       
   103 	// Delete temporary input file if any
       
   104 	if ( !m_sInputFileTemp.empty() )
       
   105 	{
       
   106 		if ( FileExists( m_sInputFileTemp.c_str() ) )
       
   107 			FileDelete( m_sInputFileTemp, false );
       
   108 	}
       
   109 	// Clean memory addresses if any
       
   110 	CleanMemoryAddresses();
       
   111 	// Delete rom symbol.
       
   112 	if ( m_pRomSymbol )
       
   113 	{
       
   114         delete m_pRomSymbol;
       
   115 		m_pRomSymbol = NULL;
       
   116 	}
       
   117 }
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CATDatParser::Analyze
       
   121 // Analyze given data file
       
   122 // -----------------------------------------------------------------------------
       
   123 int CATDatParser::Analyze()
       
   124 {
       
   125 	LOG_FUNC_ENTRY("CATDatParser::Analyze");
       
   126 	// Return if input file not set
       
   127 	if ( m_sInputFile.empty() )
       
   128 		return AT_RETURN_CODE::INVALID_DATA_FILE;
       
   129 	// If open close first
       
   130 	if ( m_In.is_open() )
       
   131 		m_In.close();
       
   132 	// Open file
       
   133 	m_In.open( m_sInputFile.c_str() );
       
   134 	if ( ! m_In.good() )
       
   135 		return AT_RETURN_CODE::INVALID_DATA_FILE;
       
   136 	try {
       
   137 		// If rom symbol file specified.
       
   138 		if ( ! m_vRomSymbolFiles.empty() )
       
   139 		{
       
   140 			// Create new rom symbol file "parser".
       
   141 			m_pRomSymbol = new CATRomSymbol();
       
   142 			m_pRomSymbol->m_bShowProgressMessages = true;
       
   143 			// Set symbol files.
       
   144 			if ( ! m_pRomSymbol->SetSymbols( m_vRomSymbolFiles ) )
       
   145 			{
       
   146 				cout << AT_MSG << "Rom/Rofs symbols error: " << m_pRomSymbol->GetError() << endl;
       
   147 				// If file open fails we delete it and will not use it.
       
   148 				delete m_pRomSymbol;
       
   149 				m_pRomSymbol = NULL;
       
   150 				cout << AT_MSG << "Analyze aborted." << endl;
       
   151 				return AT_RETURN_CODE::SYMBOL_FILE_ERROR;
       
   152 			}
       
   153 		}
       
   154 		// Return code
       
   155 		int iRet = 0;
       
   156 		// Clear variables
       
   157 		ClearParsingVariables();
       
   158 		// If output defined disable printing
       
   159 		if ( ! m_sOutputFile.empty() )
       
   160 			m_DataSaver.SetPrintFlag( false );
       
   161 		// Header
       
   162 		Header();
       
   163 		// Parsing
       
   164 		iRet = Parse();
       
   165 		// Footer
       
   166 		if ( iRet == AT_RETURN_CODE::OK )
       
   167 			Footer();
       
   168 		// If output defined save xml
       
   169 		if ( ! m_sOutputFile.empty() )
       
   170 			m_DataSaver.SaveLinesToFile( m_sOutputFile.c_str(), XML_DATA );
       
   171 		// Return
       
   172 		return iRet;
       
   173 	} catch ( int i )
       
   174 	{
       
   175 		cout << AT_MSG << "Error, Analyze failed. : " << i << endl;
       
   176 		return AT_RETURN_CODE::UNHANDLED_EXCEPTION;
       
   177 	}
       
   178 }
       
   179 // -----------------------------------------------------------------------------
       
   180 // CATDatParser::Header
       
   181 // Print header of report
       
   182 // -----------------------------------------------------------------------------
       
   183 void CATDatParser::Header()
       
   184 {
       
   185 	LOG_FUNC_ENTRY("CATDatParser::Header");
       
   186 	// Analyze report header
       
   187 	m_DataSaver.AddString( "Atool.exe v." );
       
   188 	m_DataSaver.AddString( ATOOL_VERSION );
       
   189 	m_DataSaver.AddString( "\n" );
       
   190 	m_DataSaver.AddString( "Analyzing memory leaks..." );
       
   191 	m_DataSaver.AddLineToLast();
       
   192 }
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CATDatParser::Footer
       
   196 // Print footer of report
       
   197 // -----------------------------------------------------------------------------
       
   198 void CATDatParser::Footer()
       
   199 {
       
   200 	LOG_FUNC_ENTRY("CATDatParser::Footer");
       
   201 	m_DataSaver.AddString( "\nTotal Runs: " );
       
   202 	m_DataSaver.AddInteger( m_iTotalRuns );
       
   203 	m_DataSaver.AddLineToLast();
       
   204 
       
   205 	int iFailedRuns = m_iTotalRuns - m_iSuccesfullRuns;
       
   206 	m_DataSaver.AddString( "Failed Runs: " );
       
   207 	m_DataSaver.AddInteger( iFailedRuns );
       
   208 	m_DataSaver.AddLineToLast();
       
   209 
       
   210 	char cTemp[128];
       
   211 	string sResult( itoa( m_iTotalRuns, cTemp, 10 ) );
       
   212 	sResult.append( ";" );
       
   213 	sResult.append( itoa( iFailedRuns, cTemp, 10 ) );
       
   214 	sResult.append( ";" );
       
   215 
       
   216 	m_DataSaver.SaveXML( sResult, RESULT );
       
   217 }
       
   218 
       
   219 // -----------------------------------------------------------------------------
       
   220 // CATDatParser::ClearParsingVariables
       
   221 // Clear/Reset all member variables related to parsing data file
       
   222 // -----------------------------------------------------------------------------
       
   223 void CATDatParser::ClearParsingVariables()
       
   224 {
       
   225 	LOG_FUNC_ENTRY("CATDatParser::ClearParsingVariables");
       
   226 	// Clear variables related to analyze
       
   227 	m_eProcess_state = not_started;
       
   228 	m_bProcessStartFound = false;
       
   229 	m_bDllLoadFound = false;
       
   230 	m_iTotalNumberOfLeaks = 0;
       
   231 	m_iPinPointedLeaks = 0;
       
   232 	m_iLeakNumber = 0;
       
   233 	m_iTotalRuns = 0;
       
   234 	m_iSuccesfullRuns = 0;
       
   235 	m_bSubtestOnGoing = false;
       
   236 	m_iSubtestStartHandleCount = 0;
       
   237 	CleanMemoryAddresses();
       
   238 }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // CATDatParser::Parse
       
   242 // Parses data file. Note! header and footer of the report are done in 
       
   243 // separate functions.
       
   244 // -----------------------------------------------------------------------------
       
   245 int CATDatParser::Parse()
       
   246 {
       
   247 	LOG_FUNC_ENTRY("CATDatParser::Parse");
       
   248 	// Read all lines
       
   249 	char cLine[MAX_LINE_LENGTH];
       
   250 	do
       
   251 	{
       
   252 		string sLine;
       
   253 		try {
       
   254 			m_In.getline( cLine, MAX_LINE_LENGTH );
       
   255 			sLine = cLine ;
       
   256 		} catch(...)
       
   257 		{
       
   258 			LOG_STRING( AT_MSG << "Unexpected error, reading data file." );
       
   259 			continue;
       
   260 		}
       
   261 		if( sLine.find( LABEL_DATA_FILE_VERSION ) != string::npos )
       
   262 		{
       
   263 			// Check data file version
       
   264 			if(  sLine.find( AT_DATA_FILE_VERSION ) == string::npos )
       
   265 			{
       
   266 				return AT_RETURN_CODE::WRONG_DATA_FILE_VERSION;
       
   267 			}
       
   268 		}
       
   269 		else if( sLine.find( LABEL_PROCESS_START ) != string::npos )
       
   270 		{
       
   271 			if ( ! ParseProcessStart( sLine ) )
       
   272 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   273 		}
       
   274 		else if( sLine.find( LABEL_DLL_LOAD ) != string::npos )
       
   275 		{
       
   276 			if ( ! ParseDllLoad( sLine ) )
       
   277 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   278 		}
       
   279 		else if( sLine.find( LABEL_DLL_UNLOAD ) != string::npos )
       
   280 		{
       
   281 			if ( ! ParseDllUnload( sLine ) )
       
   282 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   283 		}
       
   284 		else if( sLine.find( LABEL_MEM_LEAK ) != string::npos)
       
   285 		{
       
   286 			if ( ! ParseMemLeak( sLine ) )
       
   287 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   288 		}
       
   289 		else if( sLine.find( LABEL_PROCESS_END ) != string::npos )
       
   290 		{
       
   291 			if ( ! ParseProcessEnd( sLine ) )
       
   292 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   293 		}
       
   294 		else if( sLine.find( LABEL_ERROR_OCCURED ) != string::npos )
       
   295 		{
       
   296 			if ( ! ParseErrorOccured( sLine ) )
       
   297 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   298 		}
       
   299 		else if( sLine.find( LABEL_HANDLE_LEAK ) != string::npos )
       
   300 		{
       
   301 			if ( ! ParseHandleLeak( sLine ) )
       
   302 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   303 		}
       
   304 		else if( sLine.find( LABEL_TEST_START ) != string::npos )
       
   305 		{
       
   306 			if ( ! ParseTestStart( sLine ) )
       
   307 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   308 		}
       
   309 		else if( sLine.find( LABEL_TEST_END ) != string::npos )
       
   310 		{
       
   311 			if ( ! ParseTestEnd( sLine ) )
       
   312 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   313 		}
       
   314 		else if( sLine.find( LABEL_LOGGING_CANCELLED ) != string::npos )
       
   315 		{
       
   316 			if ( ! ParseLoggingCancelled( sLine ) )
       
   317 				return AT_RETURN_CODE::ANALYZE_ERROR;
       
   318 		}
       
   319 	}
       
   320 	while( m_In.good() );
       
   321 	// Message of failed run if process start was last line in data.
       
   322 	if ( m_eProcess_state == ongoing )
       
   323 	{
       
   324 		m_DataSaver.AddString( "Test run failed.\n" );
       
   325 		m_DataSaver.AddLineToLast();
       
   326 	}
       
   327 	return AT_RETURN_CODE::OK;
       
   328 }
       
   329 
       
   330 // -----------------------------------------------------------------------------
       
   331 // CATDatParser::ParseProcessStart
       
   332 // -----------------------------------------------------------------------------
       
   333 bool CATDatParser::ParseProcessStart( string& sLine)
       
   334 {
       
   335 	LOG_FUNC_ENTRY("CATDatParser::ParseProcessStart");
       
   336 	if ( m_eProcess_state == ongoing )
       
   337 	{
       
   338 		m_DataSaver.AddString( "Test run failed.\n" );
       
   339 		m_DataSaver.AddLineToLast();
       
   340 	}
       
   341 	m_eProcess_state = ongoing;
       
   342 	m_bProcessStartFound = true;
       
   343 
       
   344 	// Clear handle leaks
       
   345 	m_vHandleLeaks.clear();
       
   346 	// Increment runs
       
   347 	m_iTotalRuns++;
       
   348 	// Clean leak count
       
   349 	m_iTotalNumberOfLeaks = 0;
       
   350 	// Clean pin pointed leaks count.
       
   351 	m_iPinPointedLeaks = 0;
       
   352 	// Clean leak number
       
   353 	m_iLeakNumber = 0;
       
   354 
       
   355 	// Clean loaded mods
       
   356 	m_vDllLoadModList.clear();
       
   357 	m_vDllLoadModListSubTest.clear();
       
   358 
       
   359 	// Skip text PROCESS_START
       
   360 	GetStringUntilNextSpace( sLine );
       
   361 	// Get process name
       
   362 	m_sCurrentProcessName = GetStringUntilNextSpace( sLine );
       
   363 	// Get Pid
       
   364 	string sPid = GetStringUntilNextSpace( sLine );
       
   365 	m_iCurrentProcessId = _httoi( sPid.c_str() );
       
   366 
       
   367 	// Header for process start
       
   368 	m_DataSaver.AddString( "\n--------------------------------\n" );
       
   369 	m_DataSaver.AddString( "Test Run start (" );
       
   370 	m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
       
   371 	m_DataSaver.AddString( "): " );
       
   372 
       
   373 	// Get start time
       
   374 	string sTime = GetStringUntilNextSpace( sLine );
       
   375 	sTime = ConvertTimeToLocalTime( sTime );
       
   376 	m_DataSaver.AddString( sTime.c_str() );
       
   377 
       
   378 	// Create data for xml
       
   379 	string sData( sTime );
       
   380 	sData.append( ";" );
       
   381 	
       
   382 	// Build mode UDEB/UREL.
       
   383 	string sBuildType = GetStringUntilNextSpace( sLine );
       
   384 
       
   385 	m_DataSaver.AddString( " Build target: " );
       
   386 	if( sBuildType.compare( "0" ) == 0 )
       
   387 	{
       
   388 		m_eBuildType = CATProject::UREL;
       
   389 	}
       
   390 	else if( sBuildType.compare( "1" ) == 0 )
       
   391 	{
       
   392 		m_eBuildType = CATProject::UDEB;
       
   393 	}
       
   394 	m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
       
   395 
       
   396 	// Version.
       
   397 	string sVersion = GetStringUntilNextSpace( sLine );
       
   398 	unsigned int iVer = 0;
       
   399 	if ( hexToDec( sVersion, iVer ) && iVer != 0 )
       
   400 		m_iDataVersion = iVer;
       
   401 
       
   402 	// End line in data.
       
   403 	m_DataSaver.AddLineToLast();
       
   404 	
       
   405 	// xml
       
   406 	sData.append( CATProject::GetBuildTypeString( m_eBuildType ) );
       
   407 	sData.append( ";" );
       
   408 	sData.append( m_sCurrentProcessName );
       
   409 	m_DataSaver.SaveXML( sData, RUN );
       
   410 
       
   411 	// If projects platform defined check that it is same in data. (future feature).
       
   412 	if ( ! m_sProjectPlatform.empty() )
       
   413 	{
       
   414 		// If platform info is added to data file do check here.
       
   415 	}
       
   416 	// If projects build type defined check that it is same in data.
       
   417 	if ( m_eProjectBuildType != -1 )
       
   418 	{
       
   419 		if ( m_eBuildType != m_eProjectBuildType )
       
   420 		{
       
   421 			string sError(AT_MSG);
       
   422 			sError.append( "Error, analyzed data has build type of " );
       
   423 			sError.append( CATProject::GetBuildTypeString( m_eBuildType ) );
       
   424 			sError.append( " and project has build type " );
       
   425 			sError.append( CATProject::GetBuildTypeString( m_eProjectBuildType ) );
       
   426 			sError.append( ". Pinpointed code lines are not valid." );
       
   427 			m_DataSaver.AddString( sError.c_str(), false );
       
   428 			m_DataSaver.AddLineToLast();
       
   429 		}
       
   430 	}
       
   431 	return true;
       
   432 }
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CATDatParser::ParseProcessEnd
       
   436 // -----------------------------------------------------------------------------
       
   437 bool CATDatParser::ParseProcessEnd( string& sLine )
       
   438 {
       
   439 	LOG_FUNC_ENTRY("CATDatParser::ParseProcessEnd");
       
   440 	GetStringUntilNextSpace( sLine );
       
   441 
       
   442 	// Get process id
       
   443 	string sProcessID = GetStringUntilNextSpace( sLine );
       
   444 	unsigned long iProcessID = _httoi( sProcessID.c_str() );
       
   445 
       
   446 	// Get time
       
   447 	string sTime = GetStringUntilNextSpace( sLine );
       
   448 
       
   449 	// Convert leak time
       
   450 	sTime = ConvertTimeToLocalTime( sTime );
       
   451 
       
   452 	// Process started?
       
   453 	if( iProcessID == m_iCurrentProcessId )
       
   454 	{
       
   455 		m_iSuccesfullRuns++;
       
   456 		m_DataSaver.AddLineToLast();
       
   457 		m_DataSaver.AddString( "Test Run end (" );
       
   458 		m_DataSaver.AddString( m_sCurrentProcessName.c_str() );
       
   459 		m_DataSaver.AddString( "): " );
       
   460 		m_DataSaver.AddString( sTime.c_str() );
       
   461 		m_DataSaver.AddLineToLast();
       
   462 		m_DataSaver.AddString( "Build target: " );
       
   463 		m_DataSaver.AddString( CATProject::GetBuildTypeString( m_eBuildType ).c_str() );
       
   464 		m_DataSaver.AddLineToLast();
       
   465 
       
   466 		m_eProcess_state = stopped;
       
   467 		// Number of leaks
       
   468 		if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
   469 		{
       
   470 			if ( m_iPinPointedLeaks > 0 )
       
   471 			{
       
   472 				m_DataSaver.AddInteger( m_iPinPointedLeaks );
       
   473 				m_DataSaver.AddString( " number of pinpointed memory leak(s)." );
       
   474 				m_DataSaver.AddLineToLast();
       
   475 			}
       
   476 			m_DataSaver.AddInteger( m_iLeakNumber );
       
   477 			m_DataSaver.AddString( " total number of memory leak(s)." );
       
   478 			m_DataSaver.AddLineToLast();
       
   479 		}
       
   480 		else
       
   481 		{
       
   482 			m_DataSaver.AddInteger( m_iTotalNumberOfLeaks );
       
   483 			m_DataSaver.AddString( " memory leak(s) found." );
       
   484 			m_DataSaver.AddLineToLast();
       
   485 		}
       
   486 		
       
   487 		// xml
       
   488 		char cTemp[128];
       
   489 		m_DataSaver.SaveXML( itoa( m_iTotalNumberOfLeaks, cTemp, 10 ) , MEM_LEAKS );
       
   490 
       
   491 		// Print all modules which have leaks
       
   492 		for( size_t i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
   493 		{
       
   494 			if( m_vDllLoadModList.at(i).iLeaks > 0 )
       
   495 			{
       
   496 				m_DataSaver.AddInteger( m_vDllLoadModList.at(i).iLeaks );
       
   497 				m_DataSaver.AddString( " memory leak(s) in module: " );
       
   498 				m_DataSaver.AddString( m_vDllLoadModList.at(i).sModuleName.c_str() );
       
   499 				m_DataSaver.AddLineToLast();
       
   500 
       
   501 				// xml
       
   502 				string sModuleNameAndLeaks( m_vDllLoadModList[i].sModuleName );
       
   503 				sModuleNameAndLeaks.append(";");
       
   504 				sModuleNameAndLeaks.append( itoa( m_vDllLoadModList[i].iLeaks, cTemp, 10 ) );
       
   505 				m_DataSaver.SaveXML( sModuleNameAndLeaks , MEM_LEAK_MODULE );
       
   506 			}
       
   507 		}
       
   508 		
       
   509 		if ( m_vHandleLeaks.size() > 0 )
       
   510 		{
       
   511 			// We have handle leaks
       
   512 			bool bHandLeaksFound = false;
       
   513 			int iTotalNrOfLeaks = 0;
       
   514 			// Print handle leaks
       
   515 			for( size_t i = 0 ; i < m_vHandleLeaks.size() ; i++ )
       
   516 			{
       
   517 				string sTempHandleLeak( m_vHandleLeaks[i] );
       
   518 				// Count.
       
   519 				string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) );
       
   520 
       
   521 				// Name.
       
   522 				//string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) );
       
   523 				string sHandleLeakModule( "Unknown" );
       
   524 
       
   525 				unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() );
       
   526 				iTotalNrOfLeaks += iNrOfLeaks;
       
   527 				if( iNrOfLeaks )
       
   528 				{
       
   529 					if( !bHandLeaksFound )
       
   530 					{
       
   531 						m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS );
       
   532 					}
       
   533 					bHandLeaksFound = true;
       
   534 					m_DataSaver.AddInteger( iNrOfLeaks );
       
   535 					// Just print out how many leaks found.
       
   536 					// Because its always unknown.
       
   537 					m_DataSaver.AddString( " handle leak(s) found." );
       
   538 					m_DataSaver.AddLineToLast();
       
   539 
       
   540 					// xml
       
   541 					string sXMLInfo( sHandleLeakModule );
       
   542 					sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks );
       
   543 					m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE );
       
   544 				}
       
   545 			}
       
   546 			// Update number if handle leaks
       
   547 			m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS );
       
   548 			if( !bHandLeaksFound )
       
   549 			{
       
   550 				//m_DataSaver.AddLineToLast();
       
   551 				m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   552 				m_DataSaver.AddLineToLast();
       
   553 			}
       
   554 		}
       
   555 		else
       
   556 		{
       
   557 			// No handle leaks
       
   558 			m_DataSaver.AddLineToLast();
       
   559 			m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   560 			m_DataSaver.AddLineToLast();
       
   561 		}
       
   562 
       
   563 		// Process end to xml
       
   564 		m_DataSaver.SaveXML( sTime, RUN_END );
       
   565 		// Reset current process
       
   566 		m_iCurrentProcessId = 0;
       
   567 	}
       
   568 	
       
   569 	// If no dll load or process start found
       
   570 	if ( ! m_bProcessStartFound || !m_bDllLoadFound )
       
   571 	{
       
   572 		m_DataSaver.AddLineToLast();
       
   573 		m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA );
       
   574 		m_DataSaver.AddLineToLast();
       
   575 	}
       
   576 	
       
   577 	return true;
       
   578 }
       
   579 
       
   580 // -----------------------------------------------------------------------------
       
   581 // CATDatParser::ParseDllLoad
       
   582 // -----------------------------------------------------------------------------
       
   583 bool CATDatParser::ParseDllLoad( string& sLine )
       
   584 {
       
   585 	LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad");
       
   586 	//DLL_LOAD <DLL name> <Time stamp> <Memory start address> <Memory end address>
       
   587 	m_bDllLoadFound = true;
       
   588 	DLL_LOAD_INFO structDllInfo;
       
   589 	structDllInfo.iStartAddress = 0;
       
   590 	structDllInfo.iEndAddress = 0;
       
   591 	structDllInfo.iLeaks = 0;
       
   592 
       
   593 	// Skip "DLL_LOAD "
       
   594 	GetStringUntilNextSpace( sLine );
       
   595 
       
   596 	// Get module name
       
   597 	structDllInfo.sModuleName = GetStringUntilNextSpace( sLine );
       
   598 	ChangeToLower( structDllInfo.sModuleName );
       
   599 
       
   600 	// Create module from this if project platform emulator
       
   601 	if ( _stricmp( "winscw", m_sProjectPlatform.c_str() ) == 0 )
       
   602 		CreateWinscwModule( structDllInfo.sModuleName );
       
   603 
       
   604 	// Get dll start memory string address from line
       
   605 	// Convert string address to real memory address
       
   606 	structDllInfo.iStartAddress = 
       
   607 		_httoi( GetStringUntilNextSpace( sLine ).c_str() );
       
   608 
       
   609 	// Get dll end memory string address from line
       
   610 	// Convert string address to real memory address
       
   611 	structDllInfo.iEndAddress = 
       
   612 		_httoi( 
       
   613 		GetStringUntilNextSpace( sLine ).c_str() );
       
   614 
       
   615 	if ( m_iDataVersion >= AT_DLL_TIMESTAMP_DATA_VERSION )
       
   616 	{
       
   617 		// Pickup module loading time.
       
   618 		string sLoadTime = GetStringUntilNextSpace( sLine );
       
   619 		unsigned long long ull;
       
   620 		if ( hexToDec( sLoadTime, ull ) )
       
   621 			structDllInfo.iLoadTime = ull;
       
   622 	}
       
   623 
       
   624 	// Is module already loaded, if not add it to list.
       
   625 	bool bFound = false;
       
   626 	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModList.begin();
       
   627 		it != m_vDllLoadModList.end() ; it++ )
       
   628 	{
       
   629 		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
       
   630 		{
       
   631 			bFound = true;
       
   632 			break;
       
   633 		}
       
   634 	}
       
   635 	if( ! bFound )
       
   636 		m_vDllLoadModList.push_back( structDllInfo );
       
   637 
       
   638 	// Sub test module list.
       
   639 	bFound = false;
       
   640 	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModListSubTest.begin();
       
   641 		it != m_vDllLoadModListSubTest.end() ; it++ )
       
   642 	{
       
   643 		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
       
   644 		{
       
   645 			bFound = true;
       
   646 			break;
       
   647 		}
       
   648 	}
       
   649 	if( ! bFound )
       
   650 		m_vDllLoadModListSubTest.push_back( structDllInfo );
       
   651 
       
   652 	return true;
       
   653 }
       
   654 
       
   655 // -----------------------------------------------------------------------------
       
   656 // CATDatParser::ParseDllUnload
       
   657 // -----------------------------------------------------------------------------
       
   658 bool CATDatParser::ParseDllUnload( string& sLine )
       
   659 {
       
   660 	LOG_FUNC_ENTRY("CATDatParser::ParseDllUnload");
       
   661 
       
   662 	// Ignore unloads on older version because no timestamps.
       
   663 	if ( m_iDataVersion < AT_DLL_TIMESTAMP_DATA_VERSION )
       
   664 	{
       
   665 		return true;
       
   666 	}
       
   667 
       
   668 	// Skip "DLL_UNLOAD "
       
   669 	GetStringUntilNextSpace( sLine );
       
   670 
       
   671 	// Get module name
       
   672 	string sModuleName = GetStringUntilNextSpace( sLine );
       
   673 	ChangeToLower( sModuleName );
       
   674 
       
   675 	// skip adresses - not currently used
       
   676 	GetStringUntilNextSpace( sLine );
       
   677 	GetStringUntilNextSpace( sLine );
       
   678 
       
   679 	// Unload time
       
   680 	unsigned long long ull;
       
   681 	string sUnload = GetStringUntilNextSpace( sLine );
       
   682 	if ( ! hexToDec( sUnload, ull ) )
       
   683 		return true;
       
   684 
       
   685 	// Set module unload time.
       
   686 	vector<DLL_LOAD_INFO>::iterator it;
       
   687 	for( it = m_vDllLoadModList.begin() ; it != m_vDllLoadModList.end() ; it++ )
       
   688 	{
       
   689 		if ( sModuleName.compare( it->sModuleName ) == 0 )
       
   690 		{
       
   691 			(*it).iUnloadTime = ull;
       
   692 			break;
       
   693 		}
       
   694 	}
       
   695 	for( it = m_vDllLoadModListSubTest.begin() ; it != m_vDllLoadModListSubTest.end() ; it++ )
       
   696 	{
       
   697 		if ( sModuleName.compare( it->sModuleName ) == 0 )
       
   698 		{
       
   699 			(*it).iUnloadTime = ull;
       
   700 			break;
       
   701 		}
       
   702 	}
       
   703 	return true;
       
   704 }
       
   705 // -----------------------------------------------------------------------------
       
   706 // CATDatParser::ParseLoggingCancelled
       
   707 // -----------------------------------------------------------------------------
       
   708 bool CATDatParser::ParseLoggingCancelled( string& sLine )
       
   709 {
       
   710 	LOG_FUNC_ENTRY("CATDatParser::ParseLoggingCancelled");
       
   711 	// Skip text "LOGGING_CANCELLED"
       
   712 	GetStringUntilNextSpace( sLine );
       
   713 
       
   714 	// Get time
       
   715 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   716 	sTime = ConvertTimeToLocalTime( sTime );
       
   717 	m_DataSaver.AddString( "Logging Cancelled." );
       
   718 	m_DataSaver.AddLineToLast();
       
   719 	return true;
       
   720 }
       
   721 
       
   722 // -----------------------------------------------------------------------------
       
   723 // CATDatParser::ParseHandleLeak
       
   724 // -----------------------------------------------------------------------------
       
   725 bool CATDatParser::ParseHandleLeak( string& sLine )
       
   726 {
       
   727 	LOG_FUNC_ENTRY("CATDatParser::ParseHandleLeak");
       
   728 	// Skip text "HANDLE_LEAK"
       
   729 	GetStringUntilNextSpace( sLine );
       
   730 	m_vHandleLeaks.push_back( sLine );
       
   731 	return true;
       
   732 }
       
   733 
       
   734 // -----------------------------------------------------------------------------
       
   735 // CATDatParser::ParseTestStart
       
   736 // -----------------------------------------------------------------------------
       
   737 bool CATDatParser::ParseTestStart( string& sLine )
       
   738 {
       
   739 	LOG_FUNC_ENTRY("CATDatParser::ParseTestStart");
       
   740 	m_bSubtestOnGoing = true;
       
   741 	m_iLeakNumber = 0;
       
   742 	m_iPinPointedSubTestLeaks = 0;
       
   743 
       
   744 	// Reset subtest leaked modules list
       
   745 	for( size_t i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
       
   746 	{
       
   747 		m_vDllLoadModListSubTest.at(i).iLeaks = 0;
       
   748 	}
       
   749 
       
   750 	// Skip text "TEST_START"
       
   751 	GetStringUntilNextSpace( sLine );
       
   752 	// Time
       
   753 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   754 	sTime = ConvertTimeToLocalTime( sTime );
       
   755 	// Name
       
   756 	string sSubTestName( GetStringUntilNextSpace( sLine ) );				
       
   757 	m_DataSaver.AddLineToLast();
       
   758 
       
   759 	// Get handle count in subtest start
       
   760 	string sSubTestStartHandleCount( GetStringUntilNextSpace( sLine ) );
       
   761 	m_iSubtestStartHandleCount = atoi( sSubTestStartHandleCount.c_str() );
       
   762 
       
   763 	// Add start to report
       
   764 	m_DataSaver.AddString( "\nSub test (" );
       
   765 	m_DataSaver.AddString( sSubTestName.c_str() );
       
   766 	m_DataSaver.AddString( ") start: " );
       
   767 	m_DataSaver.AddString( sTime.c_str() );
       
   768 
       
   769 	// m_DataSaver.AddLineToLast();
       
   770 
       
   771 	// Add start to xml
       
   772 	string sResult( sSubTestName );
       
   773 	sResult.append( ";" );
       
   774 	sResult.append( sTime );
       
   775 	sResult.append( ";" );
       
   776 	m_DataSaver.SaveXML( sResult, TEST_START );
       
   777 	return true;
       
   778 }
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // CATDatParser::ParseTestEnd
       
   782 // -----------------------------------------------------------------------------
       
   783 bool CATDatParser::ParseTestEnd( string& sLine )
       
   784 {
       
   785 	LOG_FUNC_ENTRY("CATDatParser::ParseTestEnd");
       
   786 	// Skip text "TEST_END"
       
   787 	GetStringUntilNextSpace( sLine );
       
   788 
       
   789 	// Time
       
   790 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   791 	sTime = ConvertTimeToLocalTime( sTime );
       
   792 
       
   793 	// Name
       
   794 	string sSubTestName( GetStringUntilNextSpace( sLine ) );
       
   795 	m_DataSaver.AddLineToLast();
       
   796 
       
   797 	// Add test end info to report
       
   798 	m_DataSaver.AddString( "Sub test (" );
       
   799 	m_DataSaver.AddString( sSubTestName.c_str() );
       
   800 	m_DataSaver.AddString( ") end: " );
       
   801 	m_DataSaver.AddString( sTime.c_str() );
       
   802 	m_DataSaver.AddLineToLast();
       
   803 
       
   804 	// Leak count to report in subtest
       
   805 	if( m_iLeakNumber > 0 )
       
   806 	{
       
   807 		if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
   808 		{
       
   809 			m_DataSaver.AddInteger( m_iPinPointedSubTestLeaks );
       
   810 			m_DataSaver.AddString( " number of pinpointed memory leaks." );
       
   811 			m_DataSaver.AddLineToLast();
       
   812 			m_DataSaver.AddInteger( m_iLeakNumber );
       
   813 			m_DataSaver.AddString( " memory leaks found." );
       
   814 		}
       
   815 		else
       
   816 		{
       
   817 			m_DataSaver.AddInteger( m_iLeakNumber );
       
   818 			m_DataSaver.AddString( " memory leaks found." );
       
   819 		}
       
   820 	}
       
   821 	else
       
   822 	{
       
   823 		m_DataSaver.AddString( "No memory leaks found." );
       
   824 	}
       
   825 	m_DataSaver.AddLineToLast();
       
   826 
       
   827 	// Use sTime to store info to xml
       
   828 	sTime.append(";");
       
   829 	char cTemp[128];
       
   830 	// Print all modules whitch have leaks
       
   831 	for( unsigned int i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
       
   832 	{
       
   833 		if( m_vDllLoadModListSubTest.at(i).iLeaks > 0 )
       
   834 		{
       
   835 			// Normal report
       
   836 			m_DataSaver.AddInteger( m_vDllLoadModListSubTest[i].iLeaks );
       
   837 			m_DataSaver.AddString( " memory leaks in module: " );
       
   838 			m_DataSaver.AddString( m_vDllLoadModListSubTest.at(i).sModuleName.c_str() );
       
   839 			m_DataSaver.AddLineToLast();
       
   840 			// xml
       
   841 			string sModuleNameAndLeaks( m_vDllLoadModListSubTest.at(i).sModuleName );
       
   842 			sModuleNameAndLeaks.append(";");
       
   843 			sModuleNameAndLeaks.append( itoa( m_vDllLoadModListSubTest.at(i).iLeaks, cTemp, 10 ) );
       
   844 			m_DataSaver.SaveXML( sModuleNameAndLeaks , SUBTEST_MEM_LEAK_MODULE );
       
   845 		}
       
   846 	}
       
   847 	// Handle count
       
   848 	int iEndHandleCount = atoi( GetStringUntilNextSpace( sLine ).c_str() );
       
   849 	// Is there handle leaks in subtest?
       
   850 	if( iEndHandleCount > m_iSubtestStartHandleCount )
       
   851 	{
       
   852 		// Print normal report
       
   853 		m_DataSaver.AddInteger( iEndHandleCount - m_iSubtestStartHandleCount );
       
   854 		m_DataSaver.AddString( " handle leaks in subtest: " );
       
   855 		m_DataSaver.AddString( sSubTestName.c_str() );
       
   856 		m_DataSaver.AddString( "." );
       
   857 		m_DataSaver.AddLineToLast();
       
   858 
       
   859 		// Print handle leaks to XML
       
   860 		string sNrOfHandleLeaks( itoa( iEndHandleCount - m_iSubtestStartHandleCount, cTemp, 10 ) );
       
   861 		sNrOfHandleLeaks.append( ";" );
       
   862 		m_DataSaver.SaveXML( sNrOfHandleLeaks, SUBTEST_HANDLE_LEAKS );
       
   863 	}
       
   864 	else
       
   865 	{
       
   866 		// No handle leaks
       
   867 		m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   868 		m_DataSaver.AddLineToLast();
       
   869 	}
       
   870 	// Save xml
       
   871 	m_DataSaver.SaveXML( sTime, TEST_END );
       
   872 	// Back to normal leaks
       
   873 	m_bSubtestOnGoing = false;
       
   874 	return true;
       
   875 }
       
   876 
       
   877 // -----------------------------------------------------------------------------
       
   878 // CATDatParser::ParseErrorOccured
       
   879 // -----------------------------------------------------------------------------
       
   880 bool CATDatParser::ParseErrorOccured( string& sLine )
       
   881 {
       
   882 	LOG_FUNC_ENTRY("CATDatParser::ParseErrorOccured");
       
   883 	string sTime,sError;
       
   884 
       
   885 	// Skip text "ERROR_OCCURED:"
       
   886 	GetStringUntilNextSpace( sLine );
       
   887 
       
   888 	// Get error
       
   889 	sError = GetStringUntilNextSpace( sLine );
       
   890 	// Get and convert error time
       
   891 	sTime = GetStringUntilNextSpace( sLine );
       
   892 	sTime = ConvertTimeToLocalTime( sTime );
       
   893 
       
   894 	// Print error line
       
   895 	m_DataSaver.AddLineToLast();
       
   896 	m_DataSaver.AddString( "Error occured on: " );
       
   897 	m_DataSaver.AddString( sTime.c_str() );
       
   898 	m_DataSaver.AddString( ". " );
       
   899 	m_DataSaver.AddString( "Symbian error code: " );
       
   900 	m_DataSaver.AddString( sError.c_str() );
       
   901 	m_DataSaver.AddString( "." );
       
   902 	m_DataSaver.AddLineToLast();
       
   903 
       
   904 	return true;
       
   905 }
       
   906 
       
   907 // -----------------------------------------------------------------------------
       
   908 // CATDatParser::ParseMemLeak
       
   909 // -----------------------------------------------------------------------------
       
   910 bool CATDatParser::ParseMemLeak( string& sLine )
       
   911 {
       
   912 	LOG_FUNC_ENTRY("CATDatParser::ParseMemLeak");
       
   913 	// Increment leak count
       
   914 	if ( ! m_bSubtestOnGoing )
       
   915 		m_iTotalNumberOfLeaks++;
       
   916 
       
   917 	// Increase leak number
       
   918 	m_iLeakNumber++;
       
   919 
       
   920 	// Leak data variables
       
   921 	string sModuleName;
       
   922 	string sLeakSize;
       
   923 	string sTime;
       
   924 	unsigned long long iTime = 0;
       
   925 	string sLeakAddress;
       
   926 	
       
   927 	// Skip text "MEM_LEAK"
       
   928 	GetStringUntilNextSpace( sLine );
       
   929 	// Get leak address
       
   930 	sLeakAddress = GetStringUntilNextSpace( sLine );
       
   931 	// Get time
       
   932 	sTime = GetStringUntilNextSpace( sLine );
       
   933 	// Convert time to decimal
       
   934 	hexToDec( sTime, iTime );
       
   935 	// Get memory reserve size
       
   936 	sLeakSize = GetStringUntilNextSpace( sLine );
       
   937 	// Convert leak time
       
   938 	sTime = ConvertTimeToLocalTime( sTime );
       
   939 
       
   940 	// Loop thru call stack and put memory addresses in vector
       
   941 	CleanMemoryAddresses(); // Clean memory address vector
       
   942 	CATMemoryAddress* pMemAddr = 0;
       
   943 	vector<string> vStrings = ParseStringToVector( sLine, ' ' );
       
   944 	for( size_t i = 0; i < vStrings.size() ; i++ )
       
   945 	{
       
   946 		pMemAddr = new CATMemoryAddress( vStrings.at(i), m_iOffSet );
       
   947 		// Set address time
       
   948 		pMemAddr->SetTime( iTime );
       
   949 		// Set address module name
       
   950 		if ( pMemAddr->FindSetModuleName( &m_vDllLoadModList ) )
       
   951 		{
       
   952 			// Increment leaks in module once
       
   953 			if ( sModuleName.empty() )
       
   954 			{
       
   955 				if ( m_bSubtestOnGoing )
       
   956 					m_vDllLoadModListSubTest.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
       
   957 				else
       
   958 					m_vDllLoadModList.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
       
   959 				// Set leak's module where it was located.
       
   960 				sModuleName = pMemAddr->GetModuleName();
       
   961 			}
       
   962 		}
       
   963 		// Add it to vector
       
   964 		m_vMemoryAddress.push_back( pMemAddr );
       
   965 	}
       
   966 	// If logging level is 0 Skip printing / locating code lines for call stack items.
       
   967 	if ( m_iLogLevel == 0 )
       
   968 		return true;
       
   969 	if ( m_pModules && vStrings.size() > 0 )
       
   970 	{
       
   971 		// Have we successfully located code line for memory address
       
   972 		bool bSuccesfullAddressToLine = false;
       
   973 		for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
       
   974 		{
       
   975 			int iIndexInDll = m_vMemoryAddress.at( x )->GetDllLoadInfoIndex();
       
   976 			if ( iIndexInDll != -1 )
       
   977 			{
       
   978 				// Dll module name from data file
       
   979 				string sDllName = m_vDllLoadModList.at( iIndexInDll ).sModuleName;
       
   980 				// Find module from project. These are read from makefiles.
       
   981 				for ( size_t y = 0; y < m_pModules->size() ; y++ )
       
   982 				{
       
   983 					// Module name from project data (makefiles)
       
   984 					string sModuleName = m_pModules->at( y )->GetBinaryName();
       
   985 					// If we find module from project ones, use it to located code line for memory address
       
   986 					// Note! dll names can be pretty messy i.e. DLL_LOAD 10281fc6.dll{000a0000}[10281fc6] 81d57b88 81e60a90
       
   987 					if ( sDllName.find( sModuleName ) != string::npos )
       
   988 					{
       
   989 						m_pModules->at( y )->AddressToLine( m_vMemoryAddress.at( x ) );
       
   990 						if ( ! bSuccesfullAddressToLine )
       
   991 						{
       
   992 							int iPPState = m_vMemoryAddress.at( x )->GetAddressToLineState();
       
   993 							if ( iPPState == CATMemoryAddress::EXACT || iPPState == CATMemoryAddress::FUNCTION )
       
   994 							{
       
   995 								bSuccesfullAddressToLine = true;
       
   996 								if ( m_bSubtestOnGoing )
       
   997 									m_iPinPointedSubTestLeaks++;
       
   998 								else
       
   999 									m_iPinPointedLeaks++;
       
  1000 							}
       
  1001 						}
       
  1002 					}
       
  1003 				}
       
  1004 			}
       
  1005 		}
       
  1006 		// If rom/rofs specified we use it to try get binary and function names
       
  1007 		// for addresses currently out of process range.
       
  1008 		if ( m_pRomSymbol )
       
  1009 		{
       
  1010 			for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
       
  1011 			{
       
  1012 				if ( m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS
       
  1013 					|| m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_RANGE )
       
  1014 				{
       
  1015 					m_pRomSymbol->AddressToLine( m_vMemoryAddress.at(x) );
       
  1016 				}
       
  1017 			}
       
  1018 		}
       
  1019 	}
       
  1020 	// Print leak
       
  1021 	PrintMemLeak( sTime, sLeakSize, sLeakAddress, sModuleName);
       
  1022 	return true;
       
  1023 }
       
  1024 
       
  1025 // -----------------------------------------------------------------------------
       
  1026 // CATDatParser::PrintMemLeak
       
  1027 // -----------------------------------------------------------------------------
       
  1028 void CATDatParser::PrintMemLeak(const string& sTime,
       
  1029 							   const string& sLeakSize,
       
  1030 							   const string& sLeakAddr,
       
  1031 							   const string& sModuleName)
       
  1032 {
       
  1033 	LOG_FUNC_ENTRY("CATDatParser::PrintMemLeak");
       
  1034 	// Print header data of leak
       
  1035 	m_DataSaver.AddString("\nMemory leak ");
       
  1036 	m_DataSaver.AddInteger( m_iLeakNumber, true);
       
  1037 
       
  1038 	// Leak size
       
  1039 	m_DataSaver.AddString( " (" );
       
  1040 	m_DataSaver.AddInteger( _httoi( sLeakSize.c_str() ), true );
       
  1041 	m_DataSaver.AddString( " bytes) " );
       
  1042 
       
  1043 	// Leak address
       
  1044 	m_DataSaver.AddString("(0x");
       
  1045 	m_DataSaver.AddString( sLeakAddr.c_str(), true );
       
  1046 	m_DataSaver.AddString( ") " );
       
  1047 
       
  1048 	// Time
       
  1049 	m_DataSaver.AddString( sTime.c_str(), true );
       
  1050 	m_DataSaver.AddString( " " );
       
  1051 	
       
  1052 	// Module name
       
  1053 	m_DataSaver.AddString( sModuleName.c_str(), true );
       
  1054 	m_DataSaver.SaveCarbideDataHeader();
       
  1055 	
       
  1056 	// Add header line
       
  1057 	m_DataSaver.AddLineToLast();
       
  1058 
       
  1059 	// Print the call stack items
       
  1060 	for( size_t i = 0 ; i < m_vMemoryAddress.size() ; i++ )
       
  1061 	{
       
  1062 		// On log levels 1 & 2 we only print located code lines.
       
  1063 		#ifndef ADDR2LINE
       
  1064 		if( 
       
  1065 			( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
  1066 			&&
       
  1067 			( m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT
       
  1068 			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::FUNCTION )
       
  1069 			)
       
  1070 		{
       
  1071 			// Skips to next
       
  1072 			continue;
       
  1073 		}
       
  1074 		#endif
       
  1075 		#ifdef ADDR2LINE
       
  1076 		if( ( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
  1077 			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT )
       
  1078 		{
       
  1079 			// Skips to next
       
  1080 			continue;
       
  1081 		}
       
  1082 		#endif
       
  1083 		else if ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS )
       
  1084 		{
       
  1085 			// Is memory address out of modules range
       
  1086 			string sTemp;
       
  1087 			sTemp.append( m_vMemoryAddress.at(i)->GetAddressString() );
       
  1088 			sTemp.append( " Address out of process memory.");
       
  1089 			m_DataSaver.AddString( sTemp.c_str(), true );
       
  1090 			m_DataSaver.AddLineToLast();
       
  1091 			continue;
       
  1092 		}
       
  1093 		
       
  1094 		// Print memory address
       
  1095 		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetAddressString().c_str(), true );
       
  1096 
       
  1097 		// Space (only for console output)
       
  1098 		m_DataSaver.AddString( " " );
       
  1099 
       
  1100 		m_DataSaver.AddCarbideData( 
       
  1101 			NumberToHexString( m_vMemoryAddress.at(i)->GetOffSetFromModuleStart() ) );
       
  1102 
       
  1103 		// Module name
       
  1104 		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetModuleName().c_str(), true );
       
  1105 
       
  1106 		// Print call stack memory address details depending on state of memory address
       
  1107 		switch( m_vMemoryAddress.at(i)->GetAddressToLineState() )
       
  1108 		{
       
  1109 			// Address outside of known processes
       
  1110 		case CATMemoryAddress::OUT_OF_PROCESS:
       
  1111 			m_DataSaver.AddLineToLast();
       
  1112 			break;
       
  1113 			// Address located outside of known modules symbols
       
  1114 		case CATMemoryAddress::OUT_OF_RANGE:
       
  1115 			m_DataSaver.AddString( " " );
       
  1116 			m_DataSaver.AddString( "???", true );
       
  1117 			m_DataSaver.AddLineToLast();
       
  1118 			break;
       
  1119 		// Symbol state is currently used when using rom symbol file.
       
  1120 		// From it we get module name & function name.
       
  1121 		case CATMemoryAddress::SYMBOL:
       
  1122 			m_DataSaver.AddString( " " );
       
  1123 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1124 			if ( ! m_vMemoryAddress.at( i )->GetFileName().empty() )
       
  1125 			{
       
  1126 				m_DataSaver.AddString( " (" );
       
  1127 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1128 				m_DataSaver.AddString( ")" );
       
  1129 			}
       
  1130 			m_DataSaver.AddLineToLast();
       
  1131 			break;
       
  1132 		// Lst & Map implementation
       
  1133 		#ifndef ADDR2LINE
       
  1134 		case CATMemoryAddress::FUNCTION:
       
  1135 		case CATMemoryAddress::EXACT:
       
  1136 			m_DataSaver.AddString( " " );
       
  1137 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1138 			// Small difference displaying details depending on build urel/udeb
       
  1139 			if ( m_eBuildType == CATProject::UREL )
       
  1140 			{
       
  1141 				// UREL
       
  1142 				// Set build info to data saver
       
  1143 				m_DataSaver.SetBuild( false );
       
  1144 				// urel = functionname: linenumber (filename)
       
  1145 				m_DataSaver.AddString( ": " );
       
  1146 				if (  m_vMemoryAddress.at(i)->GetFunctionLineNumber() != -1 )
       
  1147 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
       
  1148 				else if (  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1149 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1150 				m_DataSaver.AddString( " (" );
       
  1151 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1152 				m_DataSaver.AddString( ")" );
       
  1153 				m_DataSaver.AddLineToLast();
       
  1154 			}
       
  1155 			else
       
  1156 			{
       
  1157 				// UDEB
       
  1158 				// udeb = functionname: (filename:linenumber)
       
  1159 				m_DataSaver.AddString( " (" );
       
  1160 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1161 				m_DataSaver.AddString( ":" );
       
  1162 				if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1163 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1164 				else
       
  1165 					m_DataSaver.AddString( "???", true );
       
  1166 				m_DataSaver.AddString( ")" );
       
  1167 				m_DataSaver.AddLineToLast();
       
  1168 			}
       
  1169 			break;
       
  1170 		#endif
       
  1171 		// addr2line implementation (new).
       
  1172 		#ifdef ADDR2LINE
       
  1173 		case CATMemoryAddress::FUNCTION:
       
  1174 			m_DataSaver.AddString( " " );
       
  1175 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1176 			m_DataSaver.AddString( " (" );
       
  1177 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1178 			m_DataSaver.AddString( ":" );
       
  1179 			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1180 				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
       
  1181 			else
       
  1182 				m_DataSaver.AddString( "???", true );
       
  1183 			m_DataSaver.AddString( ")" );
       
  1184 			m_DataSaver.AddLineToLast();
       
  1185 			break;
       
  1186 		case CATMemoryAddress::EXACT:
       
  1187 			m_DataSaver.AddString( " " );
       
  1188 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1189 			m_DataSaver.AddString( " (" );
       
  1190 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1191 			m_DataSaver.AddString( ":" );
       
  1192 			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1193 				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1194 			else
       
  1195 				m_DataSaver.AddString( "???", true );
       
  1196 			m_DataSaver.AddString( ")" );
       
  1197 			m_DataSaver.AddLineToLast();
       
  1198 			break;
       
  1199 		#endif
       
  1200 		} // End switch
       
  1201 		// On logging level 1 we only print one located code line
       
  1202 		#ifndef ADDR2LINE
       
  1203 		if ( m_iLogLevel == 1 && ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT ||
       
  1204 			m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::FUNCTION ) )
       
  1205 			break;
       
  1206 		#endif
       
  1207 		#ifdef ADDR2LINE
       
  1208 		if ( m_iLogLevel == 1 && m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT )
       
  1209 			break;
       
  1210 		#endif
       
  1211 	} // End call stack items loop
       
  1212 }
       
  1213 
       
  1214 // -----------------------------------------------------------------------------
       
  1215 // CATDatParser::SetInputFile
       
  1216 // -----------------------------------------------------------------------------
       
  1217 void CATDatParser::SetInputFile(const string& sInputFile)
       
  1218 {
       
  1219 	LOG_FUNC_ENTRY("CATDatParser::SetInputFile");
       
  1220 	m_sInputFile = sInputFile;
       
  1221 }
       
  1222 
       
  1223 // -----------------------------------------------------------------------------
       
  1224 // CATDatParser::SetOutputFile
       
  1225 // -----------------------------------------------------------------------------
       
  1226 void CATDatParser::SetOutputFile(const string& sOutpuFile)
       
  1227 {
       
  1228 	LOG_FUNC_ENTRY("CATDatParser::SetOutputFile");
       
  1229 	m_sOutputFile = sOutpuFile;
       
  1230 }
       
  1231 
       
  1232 // -----------------------------------------------------------------------------
       
  1233 // CATDatParser::SetRomSymbolFiles
       
  1234 // -----------------------------------------------------------------------------
       
  1235 void CATDatParser::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
       
  1236 {
       
  1237 	LOG_FUNC_ENTRY("CATDatParser::SetRomSymbolFiles");
       
  1238 	m_vRomSymbolFiles = vRomSymbolFiles;
       
  1239 }
       
  1240 
       
  1241 // -----------------------------------------------------------------------------
       
  1242 // CATDatParser::SetLogLevel
       
  1243 // -----------------------------------------------------------------------------
       
  1244 void CATDatParser::SetLogLevel(int iLogLevel)
       
  1245 {
       
  1246 	LOG_FUNC_ENTRY("CATDatParser::SetLogLevel");
       
  1247 	m_iLogLevel = iLogLevel;
       
  1248 }
       
  1249 
       
  1250 // -----------------------------------------------------------------------------
       
  1251 // CATDatParser::GetLogLevel
       
  1252 // -----------------------------------------------------------------------------
       
  1253 int CATDatParser::GetLogLevel() const
       
  1254 {
       
  1255 	LOG_LOW_FUNC_ENTRY("CATDatParser::GetLogLevel");
       
  1256 	return m_iLogLevel;
       
  1257 }
       
  1258 
       
  1259 // -----------------------------------------------------------------------------
       
  1260 // CATDatParser::CleanMemoryAddresses
       
  1261 // -----------------------------------------------------------------------------
       
  1262 void CATDatParser::CleanMemoryAddresses()
       
  1263 {
       
  1264 	LOG_LOW_FUNC_ENTRY("CATDatParser::CleanMemoryAddresses");
       
  1265 	// Cleanup memory addressses.
       
  1266 	for( vector<CATMemoryAddress*>::iterator it = m_vMemoryAddress.begin(); it != m_vMemoryAddress.end(); it++ )
       
  1267 	{
       
  1268 		delete *it;
       
  1269 	}
       
  1270 	m_vMemoryAddress.clear();
       
  1271 }
       
  1272 
       
  1273 // -----------------------------------------------------------------------------
       
  1274 // CATDatParser::ConvertTimeToLocalTime
       
  1275 // -----------------------------------------------------------------------------
       
  1276 string CATDatParser::ConvertTimeToLocalTime( string sInputTime )
       
  1277 {
       
  1278 	LOG_LOW_FUNC_ENTRY("CATDatParser::ConvertTimeToLocalTime");
       
  1279 	//Is process end abnormal?
       
  1280 	if( sInputTime.compare( LABEL_ABNORMAL ) == 0 )
       
  1281 	{
       
  1282 		return string( AT_ANALYZE_ABNORMAL_EXIT );
       
  1283 	}
       
  1284 	else
       
  1285 	// Check that input time is at least 32-bit
       
  1286 	if( sInputTime.length() <= 8 )
       
  1287 	{
       
  1288 		sInputTime.clear();
       
  1289 		return sInputTime;
       
  1290 	}
       
  1291 
       
  1292 	string sTemp = sInputTime;
       
  1293 	const char* pTemp = sTemp.c_str();
       
  1294 
       
  1295 	// Are all characters hex
       
  1296 	for( unsigned int i = 0 ; i < sTemp.size() ; i++ )
       
  1297 	{
       
  1298 		if( !IsHexCharacter( (pTemp + i) ) )
       
  1299 		{
       
  1300 			return sInputTime;
       
  1301 		}
       
  1302 	}
       
  1303 	
       
  1304 	// Get LSB bits
       
  1305 	string sLsb;
       
  1306 	sLsb.append( sInputTime.substr( sInputTime.length()-8, sInputTime.length() ) );
       
  1307 	unsigned int iLsbTime = (unsigned int)_httoi( sLsb.c_str() );
       
  1308 
       
  1309 	// Get MSB bits
       
  1310     string sMsb;
       
  1311 	sMsb.append( sInputTime.substr( 0, sInputTime.length()-8 ) );
       
  1312 	unsigned int iMsbTime = (unsigned int)_httoi( sMsb.c_str() );
       
  1313 
       
  1314 	// Get time in microsecods
       
  1315 	long long sdf = iMsbTime * 0x100000000 + iLsbTime;
       
  1316 
       
  1317 	// Get original time (starting at year 1970 )
       
  1318 	long long llOrigTime = sdf;
       
  1319 
       
  1320 	// Get seconds
       
  1321 	sdf = ( sdf )/1000000;
       
  1322 		
       
  1323 	// Check that sdf contains some time value
       
  1324 	if( sdf <= 0)
       
  1325 	{
       
  1326 		// Error in time calculation
       
  1327 		// Return empty string
       
  1328 		sInputTime.clear();
       
  1329 		return sInputTime;
       
  1330 	}
       
  1331 
       
  1332 	// Original time after year 1970 in seconds
       
  1333 	long long llOrignTimeInSeconds = sdf;
       
  1334 	
       
  1335 	// Calculate new time which does not include millisecods
       
  1336 	long long llDiffTime = (llOrignTimeInSeconds * 1000000);
       
  1337 
       
  1338 	// Calculate time difference in milliseconds
       
  1339 	int llDiffTimeInMilliSecods = (int)( llOrigTime - llDiffTime )/1000;
       
  1340 	
       
  1341 	// Convert difference time to char
       
  1342 	char cDiffInMilliSeconds[20];
       
  1343     _itoa( llDiffTimeInMilliSecods, cDiffInMilliSeconds, 10 );
       
  1344 
       
  1345 	// Time info structure
       
  1346 	struct tm *timeinfo;
       
  1347 
       
  1348 	// Get local time
       
  1349 	timeinfo = localtime ( (time_t*) &sdf );
       
  1350 
       
  1351 	// Create string and append memory leak time to it
       
  1352 	string sTime;
       
  1353 	sTime.append( asctime( timeinfo ) );
       
  1354 
       
  1355 	// Remove last char of locale time string which is \n
       
  1356 	sTime.resize( (int)sTime.length()-1 );
       
  1357 	
       
  1358 	// Get last space index
       
  1359 	int iLastSpace = (int)sTime.find_last_of(" ");
       
  1360 
       
  1361 	// If last space index is valid
       
  1362 	if( iLastSpace <= (int)sTime.length() && iLastSpace > 0)
       
  1363 	{
       
  1364 		string sTempTime;
       
  1365 		// Append first part of original time string
       
  1366 		sTempTime.append( sTime.substr( 0, iLastSpace ) );
       
  1367 		
       
  1368 		// Append millisecods
       
  1369 		sTempTime.append( "." );
       
  1370 		sTempTime.append( cDiffInMilliSeconds );
       
  1371 
       
  1372 		// Append the rest of the original time string part
       
  1373 		sTempTime.append( sTime.substr( iLastSpace, sTime.length()));
       
  1374 
       
  1375 		// Clear original and append new time string which includes millisecods
       
  1376 		sTime.clear();
       
  1377 		sTime.append( sTempTime );
       
  1378 	}
       
  1379 
       
  1380 	// Return memory leak time
       
  1381 	return sTime.c_str();
       
  1382 }
       
  1383 
       
  1384 bool CATDatParser::CreateWinscwModule( const string& sBinaryName )
       
  1385 {
       
  1386 	LOG_FUNC_ENTRY( "CATDatParser::CreateWinscwModule" );
       
  1387 	// Is module already created?
       
  1388 	for( vector<CATModule2*>::iterator it = m_pModules->begin(); it != m_pModules->end(); it++ )
       
  1389 	{
       
  1390 		if ( _stricmp( sBinaryName.c_str(), (*it)->GetBinaryName().c_str() ) == 0 )
       
  1391 			return true;
       
  1392 	}
       
  1393 	// No create new one and set its values.
       
  1394 	CATModule2* mod = new CATModule2();
       
  1395 	mod->SetTarget( RemovePathAndExt( sBinaryName, true ) );
       
  1396 	mod->SetRequestedTargetExt( GetExtension( sBinaryName ) );
       
  1397 	mod->SetReleasePath( string( "\\epoc32\\release" ) );
       
  1398 	if ( m_eBuildType == CATProject::UDEB )
       
  1399 		mod->SetFullVariantPath( string( "winscw\\udeb" ) );
       
  1400 	else
       
  1401 		mod->SetFullVariantPath( string( "winscw\\urel" ) );
       
  1402 	mod->SetVariantPlatform( string( "winscw" ) );
       
  1403 	m_pModules->push_back( mod );
       
  1404 	return true;
       
  1405 }
       
  1406 
       
  1407 // -----------------------------------------------------------------------------
       
  1408 // CATDatParser::FindModuleUsingAddress
       
  1409 // Function finds module using given address.
       
  1410 // -----------------------------------------------------------------------------
       
  1411 int CATDatParser::FindModuleUsingAddress( unsigned long iAddress ) const
       
  1412 {
       
  1413 	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingAddress");
       
  1414 	int iRet = -1;
       
  1415 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1416 	{
       
  1417 		// Is address between start and end address?
       
  1418 		if( iAddress > m_vDllLoadModList[i].iStartAddress && iAddress < m_vDllLoadModList[i].iEndAddress )
       
  1419 		{
       
  1420 			iRet = i;
       
  1421 			break;
       
  1422 		}	
       
  1423 	}
       
  1424 	return iRet;
       
  1425 }
       
  1426 
       
  1427 // -----------------------------------------------------------------------------
       
  1428 // CATDatParser::FindModuleUsingPID
       
  1429 // Function finds module using module id.
       
  1430 // -----------------------------------------------------------------------------
       
  1431 /*
       
  1432 int CATDatParser::FindModuleUsingPID( unsigned long iPID ) const
       
  1433 {
       
  1434 	LOG_FUNC_ENTRY("CATDatParser::FindModuleUsingPID");
       
  1435 
       
  1436 	int iRet = -1;
       
  1437 
       
  1438 	// Change module name characters to lowercase
       
  1439 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1440 	{
       
  1441 		if( m_vDllLoadModList[i].iPID == iPID )
       
  1442 		{
       
  1443 			iRet = i;
       
  1444 			break;
       
  1445 		}	
       
  1446 	}
       
  1447 	return iRet;
       
  1448 }
       
  1449 */
       
  1450 // -----------------------------------------------------------------------------
       
  1451 // CATDatParser::FindModuleUsingName
       
  1452 // Function finds module using module name.
       
  1453 // -----------------------------------------------------------------------------
       
  1454 int CATDatParser::FindModuleUsingName( const char* pModName )
       
  1455 {
       
  1456 	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingName");
       
  1457 
       
  1458 	// Mod name empty?
       
  1459 	if( pModName == NULL || *pModName == 0 )
       
  1460 		return -1;
       
  1461 
       
  1462 	int iRet = -1;
       
  1463 	string sModName( pModName );
       
  1464 	// Change module name characters to lowercase
       
  1465 	ChangeToLower( sModName );
       
  1466 	// Remove variant marks (dots)
       
  1467 	RemoveAllAfterDotIfTwoDots( sModName);
       
  1468 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1469 	{
       
  1470 		string sTemp( m_vDllLoadModList[i].sModuleName );
       
  1471 		ChangeToLower( sTemp );
       
  1472 		// Remove variant marks (dots)
       
  1473 		RemoveAllAfterDotIfTwoDots( sTemp );
       
  1474 		if( sTemp.find( sModName ) != string::npos )
       
  1475 		{
       
  1476 			iRet = i;
       
  1477 			break;
       
  1478 		}	
       
  1479 	}
       
  1480 	return iRet;
       
  1481 }
       
  1482 
       
  1483 // -----------------------------------------------------------------------------
       
  1484 // CATDatParser::SetPrintFlag
       
  1485 // -----------------------------------------------------------------------------
       
  1486 void CATDatParser::SetPringFlag( bool bPrintFlag )
       
  1487 {
       
  1488 	LOG_FUNC_ENTRY("CATDatParser::SetPringFlag");
       
  1489 	m_DataSaver.SetPrintFlag( bPrintFlag );
       
  1490 }
       
  1491 // -----------------------------------------------------------------------------
       
  1492 // CATDatParser::SetOffSet
       
  1493 // -----------------------------------------------------------------------------
       
  1494 void CATDatParser::SetOffSet( int iOffSet )
       
  1495 {
       
  1496 	LOG_FUNC_ENTRY("CATDatParser::SetOffSet");
       
  1497 	m_iOffSet = iOffSet;
       
  1498 }
       
  1499 
       
  1500 // -----------------------------------------------------------------------------
       
  1501 // CATDatParser::GetOffSet
       
  1502 // -----------------------------------------------------------------------------
       
  1503 int CATDatParser::GetOffSet( ) const
       
  1504 {
       
  1505 	LOG_LOW_FUNC_ENTRY("CATDatParser::GetOffSet");
       
  1506 	return m_iOffSet;
       
  1507 }
       
  1508 
       
  1509 // -----------------------------------------------------------------------------
       
  1510 // Set project platform.
       
  1511 // -----------------------------------------------------------------------------
       
  1512 void CATDatParser::SetProjectPlatform( const string& sPlatform )
       
  1513 {
       
  1514 	LOG_FUNC_ENTRY("CATDatParser::SetProjectPlatform");
       
  1515 	m_sProjectPlatform = sPlatform;
       
  1516 
       
  1517 	// Check that platform not empty before determing platform from it.
       
  1518 	if ( sPlatform.empty() )
       
  1519 		return;
       
  1520 
       
  1521 	// Set functions offset in mapfiles correct (depending on platform).
       
  1522 	if ( _stricmp( sPlatform.c_str(), "armv5" ) == 0 )
       
  1523 	{
       
  1524 		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5;
       
  1525 	}
       
  1526 	else if ( _stricmp( sPlatform.c_str(), "winscw" ) == 0 )
       
  1527 	{
       
  1528 		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW;
       
  1529 	}
       
  1530 	else if ( _stricmp( sPlatform.c_str(), "gcce" ) == 0 )
       
  1531 	{
       
  1532 		m_iOffSet = FUNCTIONS_OFFSET_IN_GCCE;
       
  1533 	}
       
  1534 	else
       
  1535 	{
       
  1536 		LOG_STRING( AT_MSG << "Error, cannot set function's offset in map file, invalid platform: " << sPlatform );
       
  1537 	}
       
  1538 }
       
  1539 
       
  1540 // -----------------------------------------------------------------------------
       
  1541 // Set projects build type. Use enumeration defined in CATProject.
       
  1542 // -----------------------------------------------------------------------------
       
  1543 void CATDatParser::SetProjectBuildType( int eBuildType )
       
  1544 {
       
  1545 	LOG_FUNC_ENTRY("CATDatParser::SetProjectBuildType");
       
  1546 	m_eProjectBuildType = eBuildType;
       
  1547 }
       
  1548 
       
  1549 //EOF