memana/analyzetoolclient/commandlineengine/internal/src/CATDatParser.cpp
changeset 2 6a82cd05fb1e
parent 1 3ff3fecb12fe
equal deleted inserted replaced
1:3ff3fecb12fe 2:6a82cd05fb1e
     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 = PROCESS_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 == PROCESS_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 == PROCESS_STATE::ongoing )
       
   337 	{
       
   338 		m_DataSaver.AddString( "Test run failed.\n" );
       
   339 		m_DataSaver.AddLineToLast();
       
   340 	}
       
   341 	m_eProcess_state = PROCESS_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 tart
       
   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 = PROCESS_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 				// Name.
       
   519 				string sHandleLeakModule( GetStringUntilNextSpace( sTempHandleLeak ) );
       
   520 				// Count.
       
   521 				string sNrOfLeaks( GetStringUntilNextSpace(sTempHandleLeak) );
       
   522 				unsigned long iNrOfLeaks = _httoi( sNrOfLeaks.c_str() );
       
   523 				iTotalNrOfLeaks += iNrOfLeaks;
       
   524 				if( iNrOfLeaks )
       
   525 				{
       
   526 					if( !bHandLeaksFound )
       
   527 					{
       
   528 						m_DataSaver.SaveXML( sNrOfLeaks , HANDLE_LEAKS );
       
   529 					}
       
   530 					bHandLeaksFound = true;
       
   531 					m_DataSaver.AddInteger( iNrOfLeaks );
       
   532 					// Just print out how many leaks found.
       
   533 					// Because its always unknown.
       
   534 					m_DataSaver.AddString( " handle leak(s) found." );
       
   535 					m_DataSaver.AddLineToLast();
       
   536 
       
   537 					// xml
       
   538 					string sXMLInfo( sHandleLeakModule );
       
   539 					sXMLInfo.append( ";" ); sXMLInfo.append( sNrOfLeaks );
       
   540 					m_DataSaver.SaveXML( sXMLInfo , HANDLE_LEAK_MODULE );
       
   541 				}
       
   542 			}
       
   543 			// Update number if handle leaks
       
   544 			m_DataSaver.SaveXML( itoa( iTotalNrOfLeaks, cTemp, 10 ) , HANDLE_LEAKS );
       
   545 			if( !bHandLeaksFound )
       
   546 			{
       
   547 				//m_DataSaver.AddLineToLast();
       
   548 				m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   549 				m_DataSaver.AddLineToLast();
       
   550 			}
       
   551 		}
       
   552 		else
       
   553 		{
       
   554 			// No handle leaks
       
   555 			m_DataSaver.AddLineToLast();
       
   556 			m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   557 			m_DataSaver.AddLineToLast();
       
   558 		}
       
   559 
       
   560 		// Process end to xml
       
   561 		m_DataSaver.SaveXML( sTime, RUN_END );
       
   562 		// Reset current process
       
   563 		m_iCurrentProcessId = 0;
       
   564 	}
       
   565 	
       
   566 	// If no dll load or process start found
       
   567 	if ( ! m_bProcessStartFound || !m_bDllLoadFound )
       
   568 	{
       
   569 		m_DataSaver.AddLineToLast();
       
   570 		m_DataSaver.AddString( AT_ANALYZE_INSUFFICIENT_LOGGING_DATA );
       
   571 		m_DataSaver.AddLineToLast();
       
   572 	}
       
   573 	
       
   574 	return true;
       
   575 }
       
   576 
       
   577 // -----------------------------------------------------------------------------
       
   578 // CATDatParser::ParseDllLoad
       
   579 // -----------------------------------------------------------------------------
       
   580 bool CATDatParser::ParseDllLoad( string& sLine )
       
   581 {
       
   582 	LOG_FUNC_ENTRY("CATDatParser::ParseDllLoad");
       
   583 	//DLL_LOAD <DLL name> <Time stamp> <Memory start address> <Memory end address>
       
   584 	m_bDllLoadFound = true;
       
   585 	DLL_LOAD_INFO structDllInfo;
       
   586 	structDllInfo.iStartAddress = 0;
       
   587 	structDllInfo.iEndAddress = 0;
       
   588 	structDllInfo.iLeaks = 0;
       
   589 
       
   590 	// Skip "DLL_LOAD "
       
   591 	GetStringUntilNextSpace( sLine );
       
   592 
       
   593 	// Get module name
       
   594 	structDllInfo.sModuleName = GetStringUntilNextSpace( sLine );
       
   595 	ChangeToLower( structDllInfo.sModuleName );
       
   596 
       
   597 	// Create module from this if project platform emulator
       
   598 	if ( _stricmp( "winscw", m_sProjectPlatform.c_str() ) == 0 )
       
   599 		CreateWinscwModule( structDllInfo.sModuleName );
       
   600 
       
   601 	if ( m_iDataVersion >= AT_DLL_TIMESTAMP_DATA_VERSION )
       
   602 	{
       
   603 		// Pickup module loading time.
       
   604 		string sLoadTime = GetStringUntilNextSpace( sLine );
       
   605 		unsigned long long ull;
       
   606 		if ( hexToDec( sLoadTime, ull ) )
       
   607 			structDllInfo.iLoadTime = ull;
       
   608 	}
       
   609 
       
   610 	// Get dll start memory string address from line
       
   611 	// Convert string address to real memory address
       
   612 	structDllInfo.iStartAddress = 
       
   613 		_httoi( GetStringUntilNextSpace( sLine ).c_str() );
       
   614 
       
   615 	// Get dll end memory string address from line
       
   616 	// Convert string address to real memory address
       
   617 	structDllInfo.iEndAddress = 
       
   618 		_httoi( 
       
   619 		GetStringUntilNextSpace( sLine ).c_str() );
       
   620 
       
   621 	// Is module already loaded, if not add it to list.
       
   622 	bool bFound = false;
       
   623 	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModList.begin();
       
   624 		it != m_vDllLoadModList.end() ; it++ )
       
   625 	{
       
   626 		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
       
   627 		{
       
   628 			bFound = true;
       
   629 			break;
       
   630 		}
       
   631 	}
       
   632 	if( ! bFound )
       
   633 		m_vDllLoadModList.push_back( structDllInfo );
       
   634 
       
   635 	// Sub test module list.
       
   636 	bFound = false;
       
   637 	for( vector<DLL_LOAD_INFO>::iterator it = m_vDllLoadModListSubTest.begin();
       
   638 		it != m_vDllLoadModListSubTest.end() ; it++ )
       
   639 	{
       
   640 		if( (*it).sModuleName.compare( structDllInfo.sModuleName ) == 0 )
       
   641 		{
       
   642 			bFound = true;
       
   643 			break;
       
   644 		}
       
   645 	}
       
   646 	if( ! bFound )
       
   647 		m_vDllLoadModListSubTest.push_back( structDllInfo );
       
   648 
       
   649 	return true;
       
   650 }
       
   651 
       
   652 // -----------------------------------------------------------------------------
       
   653 // CATDatParser::ParseDllUnload
       
   654 // -----------------------------------------------------------------------------
       
   655 bool CATDatParser::ParseDllUnload( string& sLine )
       
   656 {
       
   657 	LOG_FUNC_ENTRY("CATDatParser::ParseDllUnload");
       
   658 
       
   659 	// Ignore unloads on older version because no timestamps.
       
   660 	if ( m_iDataVersion < AT_DLL_TIMESTAMP_DATA_VERSION )
       
   661 	{
       
   662 		return true;
       
   663 	}
       
   664 
       
   665 	// Skip "DLL_UNLOAD "
       
   666 	GetStringUntilNextSpace( sLine );
       
   667 
       
   668 	// Get module name
       
   669 	string sModuleName = GetStringUntilNextSpace( sLine );
       
   670 	ChangeToLower( sModuleName );
       
   671 
       
   672 	// Unload time
       
   673 	unsigned long long ull;
       
   674 	string sUnload = GetStringUntilNextSpace( sLine );
       
   675 	if ( ! hexToDec( sUnload, ull ) )
       
   676 		return true;
       
   677 
       
   678 	// Set module unload time.
       
   679 	vector<DLL_LOAD_INFO>::iterator it;
       
   680 	for( it = m_vDllLoadModList.begin() ; it != m_vDllLoadModList.end() ; it++ )
       
   681 	{
       
   682 		if ( sModuleName.compare( it->sModuleName ) == 0 )
       
   683 		{
       
   684 			(*it).iUnloadTime = ull;
       
   685 			break;
       
   686 		}
       
   687 	}
       
   688 	for( it = m_vDllLoadModListSubTest.begin() ; it != m_vDllLoadModListSubTest.end() ; it++ )
       
   689 	{
       
   690 		if ( sModuleName.compare( it->sModuleName ) == 0 )
       
   691 		{
       
   692 			(*it).iUnloadTime = ull;
       
   693 			break;
       
   694 		}
       
   695 	}
       
   696 	return true;
       
   697 }
       
   698 // -----------------------------------------------------------------------------
       
   699 // CATDatParser::ParseLoggingCancelled
       
   700 // -----------------------------------------------------------------------------
       
   701 bool CATDatParser::ParseLoggingCancelled( string& sLine )
       
   702 {
       
   703 	LOG_FUNC_ENTRY("CATDatParser::ParseLoggingCancelled");
       
   704 	// Skip text "LOGGING_CANCELLED"
       
   705 	GetStringUntilNextSpace( sLine );
       
   706 
       
   707 	// Get time
       
   708 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   709 	sTime = ConvertTimeToLocalTime( sTime );
       
   710 	m_DataSaver.AddString( "Logging Cancelled." );
       
   711 	m_DataSaver.AddLineToLast();
       
   712 	return true;
       
   713 }
       
   714 
       
   715 // -----------------------------------------------------------------------------
       
   716 // CATDatParser::ParseHandleLeak
       
   717 // -----------------------------------------------------------------------------
       
   718 bool CATDatParser::ParseHandleLeak( string& sLine )
       
   719 {
       
   720 	LOG_FUNC_ENTRY("CATDatParser::ParseHandleLeak");
       
   721 	// Skip text "HANDLE_LEAK"
       
   722 	GetStringUntilNextSpace( sLine );
       
   723 	m_vHandleLeaks.push_back( sLine );
       
   724 	return true;
       
   725 }
       
   726 
       
   727 // -----------------------------------------------------------------------------
       
   728 // CATDatParser::ParseTestStart
       
   729 // -----------------------------------------------------------------------------
       
   730 bool CATDatParser::ParseTestStart( string& sLine )
       
   731 {
       
   732 	LOG_FUNC_ENTRY("CATDatParser::ParseTestStart");
       
   733 	m_bSubtestOnGoing = true;
       
   734 	m_iLeakNumber = 0;
       
   735 	m_iPinPointedSubTestLeaks = 0;
       
   736 
       
   737 	// Reset subtest leaked modules list
       
   738 	for( size_t i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
       
   739 	{
       
   740 		m_vDllLoadModListSubTest.at(i).iLeaks = 0;
       
   741 	}
       
   742 
       
   743 	// Skip text "TEST_START"
       
   744 	GetStringUntilNextSpace( sLine );
       
   745 	// Time
       
   746 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   747 	sTime = ConvertTimeToLocalTime( sTime );
       
   748 	// Name
       
   749 	string sSubTestName( GetStringUntilNextSpace( sLine ) );				
       
   750 	m_DataSaver.AddLineToLast();
       
   751 
       
   752 	// Get handle count in subtest start
       
   753 	string sSubTestStartHandleCount( GetStringUntilNextSpace( sLine ) );
       
   754 	m_iSubtestStartHandleCount = atoi( sSubTestStartHandleCount.c_str() );
       
   755 
       
   756 	// Add start to report
       
   757 	m_DataSaver.AddString( "\nSub test (" );
       
   758 	m_DataSaver.AddString( sSubTestName.c_str() );
       
   759 	m_DataSaver.AddString( ") start: " );
       
   760 	m_DataSaver.AddString( sTime.c_str() );
       
   761 
       
   762 	// m_DataSaver.AddLineToLast();
       
   763 
       
   764 	// Add start to xml
       
   765 	string sResult( sSubTestName );
       
   766 	sResult.append( ";" );
       
   767 	sResult.append( sTime );
       
   768 	sResult.append( ";" );
       
   769 	m_DataSaver.SaveXML( sResult, TEST_START );
       
   770 	return true;
       
   771 }
       
   772 
       
   773 // -----------------------------------------------------------------------------
       
   774 // CATDatParser::ParseTestEnd
       
   775 // -----------------------------------------------------------------------------
       
   776 bool CATDatParser::ParseTestEnd( string& sLine )
       
   777 {
       
   778 	LOG_FUNC_ENTRY("CATDatParser::ParseTestEnd");
       
   779 	// Skip text "TEST_END"
       
   780 	GetStringUntilNextSpace( sLine );
       
   781 
       
   782 	// Time
       
   783 	string sTime( GetStringUntilNextSpace( sLine ) );
       
   784 	sTime = ConvertTimeToLocalTime( sTime );
       
   785 
       
   786 	// Name
       
   787 	string sSubTestName( GetStringUntilNextSpace( sLine ) );
       
   788 	m_DataSaver.AddLineToLast();
       
   789 
       
   790 	// Add test end info to report
       
   791 	m_DataSaver.AddString( "Sub test (" );
       
   792 	m_DataSaver.AddString( sSubTestName.c_str() );
       
   793 	m_DataSaver.AddString( ") end: " );
       
   794 	m_DataSaver.AddString( sTime.c_str() );
       
   795 	m_DataSaver.AddLineToLast();
       
   796 
       
   797 	// Leak count to report in subtest
       
   798 	if( m_iLeakNumber > 0 )
       
   799 	{
       
   800 		if ( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
   801 		{
       
   802 			m_DataSaver.AddInteger( m_iPinPointedSubTestLeaks );
       
   803 			m_DataSaver.AddString( " number of pinpointed memory leaks." );
       
   804 			m_DataSaver.AddLineToLast();
       
   805 			m_DataSaver.AddInteger( m_iLeakNumber );
       
   806 			m_DataSaver.AddString( " memory leaks found." );
       
   807 		}
       
   808 		else
       
   809 		{
       
   810 			m_DataSaver.AddInteger( m_iLeakNumber );
       
   811 			m_DataSaver.AddString( " memory leaks found." );
       
   812 		}
       
   813 	}
       
   814 	else
       
   815 	{
       
   816 		m_DataSaver.AddString( "No memory leaks found." );
       
   817 	}
       
   818 	m_DataSaver.AddLineToLast();
       
   819 
       
   820 	// Use sTime to store info to xml
       
   821 	sTime.append(";");
       
   822 	char cTemp[128];
       
   823 	// Print all modules whitch have leaks
       
   824 	for( unsigned int i = 0 ; i < m_vDllLoadModListSubTest.size() ; i++ )
       
   825 	{
       
   826 		if( m_vDllLoadModListSubTest.at(i).iLeaks > 0 )
       
   827 		{
       
   828 			// Normal report
       
   829 			m_DataSaver.AddInteger( m_vDllLoadModListSubTest[i].iLeaks );
       
   830 			m_DataSaver.AddString( " memory leaks in module: " );
       
   831 			m_DataSaver.AddString( m_vDllLoadModListSubTest.at(i).sModuleName.c_str() );
       
   832 			m_DataSaver.AddLineToLast();
       
   833 			// xml
       
   834 			string sModuleNameAndLeaks( m_vDllLoadModListSubTest.at(i).sModuleName );
       
   835 			sModuleNameAndLeaks.append(";");
       
   836 			sModuleNameAndLeaks.append( itoa( m_vDllLoadModListSubTest.at(i).iLeaks, cTemp, 10 ) );
       
   837 			m_DataSaver.SaveXML( sModuleNameAndLeaks , SUBTEST_MEM_LEAK_MODULE );
       
   838 		}
       
   839 	}
       
   840 	// Handle count
       
   841 	int iEndHandleCount = atoi( GetStringUntilNextSpace( sLine ).c_str() );
       
   842 	// Is there handle leaks in subtest?
       
   843 	if( iEndHandleCount > m_iSubtestStartHandleCount )
       
   844 	{
       
   845 		// Print normal report
       
   846 		m_DataSaver.AddInteger( iEndHandleCount - m_iSubtestStartHandleCount );
       
   847 		m_DataSaver.AddString( " handle leaks in subtest: " );
       
   848 		m_DataSaver.AddString( sSubTestName.c_str() );
       
   849 		m_DataSaver.AddString( "." );
       
   850 		m_DataSaver.AddLineToLast();
       
   851 
       
   852 		// Print handle leaks to XML
       
   853 		string sNrOfHandleLeaks( itoa( iEndHandleCount - m_iSubtestStartHandleCount, cTemp, 10 ) );
       
   854 		sNrOfHandleLeaks.append( ";" );
       
   855 		m_DataSaver.SaveXML( sNrOfHandleLeaks, SUBTEST_HANDLE_LEAKS );
       
   856 	}
       
   857 	else
       
   858 	{
       
   859 		// No handle leaks
       
   860 		m_DataSaver.AddString( TEXT_NO_HANDLE_LEAKS );
       
   861 		m_DataSaver.AddLineToLast();
       
   862 	}
       
   863 	// Save xml
       
   864 	m_DataSaver.SaveXML( sTime, TEST_END );
       
   865 	// Back to normal leaks
       
   866 	m_bSubtestOnGoing = false;
       
   867 	return true;
       
   868 }
       
   869 
       
   870 // -----------------------------------------------------------------------------
       
   871 // CATDatParser::ParseErrorOccured
       
   872 // -----------------------------------------------------------------------------
       
   873 bool CATDatParser::ParseErrorOccured( string& sLine )
       
   874 {
       
   875 	LOG_FUNC_ENTRY("CATDatParser::ParseErrorOccured");
       
   876 	string sTime,sError;
       
   877 
       
   878 	// Skip text "ERROR_OCCURED:"
       
   879 	GetStringUntilNextSpace( sLine );
       
   880 
       
   881 	// Get error
       
   882 	sError = GetStringUntilNextSpace( sLine );
       
   883 	// Get and convert error time
       
   884 	sTime = GetStringUntilNextSpace( sLine );
       
   885 	sTime = ConvertTimeToLocalTime( sTime );
       
   886 
       
   887 	// Print error line
       
   888 	m_DataSaver.AddLineToLast();
       
   889 	m_DataSaver.AddString( "Error occured on: " );
       
   890 	m_DataSaver.AddString( sTime.c_str() );
       
   891 	m_DataSaver.AddString( ". " );
       
   892 	m_DataSaver.AddString( "Symbian error code: " );
       
   893 	m_DataSaver.AddString( sError.c_str() );
       
   894 	m_DataSaver.AddString( "." );
       
   895 	m_DataSaver.AddLineToLast();
       
   896 
       
   897 	return true;
       
   898 }
       
   899 
       
   900 // -----------------------------------------------------------------------------
       
   901 // CATDatParser::ParseMemLeak
       
   902 // -----------------------------------------------------------------------------
       
   903 bool CATDatParser::ParseMemLeak( string& sLine )
       
   904 {
       
   905 	LOG_FUNC_ENTRY("CATDatParser::ParseMemLeak");
       
   906 	// Increment leak count
       
   907 	if ( ! m_bSubtestOnGoing )
       
   908 		m_iTotalNumberOfLeaks++;
       
   909 
       
   910 	// Increase leak number
       
   911 	m_iLeakNumber++;
       
   912 
       
   913 	// Leak data variables
       
   914 	string sModuleName;
       
   915 	string sLeakSize;
       
   916 	string sTime;
       
   917 	unsigned long long iTime = 0;
       
   918 	string sLeakAddress;
       
   919 	
       
   920 	// Skip text "MEM_LEAK"
       
   921 	GetStringUntilNextSpace( sLine );
       
   922 	// Get leak address
       
   923 	sLeakAddress = GetStringUntilNextSpace( sLine );
       
   924 	// Get time
       
   925 	sTime = GetStringUntilNextSpace( sLine );
       
   926 	// Convert time to decimal
       
   927 	hexToDec( sTime, iTime );
       
   928 	// Get memory reserve size
       
   929 	sLeakSize = GetStringUntilNextSpace( sLine );
       
   930 	// Convert leak time
       
   931 	sTime = ConvertTimeToLocalTime( sTime );
       
   932 
       
   933 	// Loop thru call stack and put memory addresses in vector
       
   934 	CleanMemoryAddresses(); // Clean memory address vector
       
   935 	CATMemoryAddress* pMemAddr = 0;
       
   936 	vector<string> vStrings = ParseStringToVector( sLine, ' ' );
       
   937 	for( size_t i = 0; i < vStrings.size() ; i++ )
       
   938 	{
       
   939 		pMemAddr = new CATMemoryAddress( vStrings.at(i), m_iOffSet );
       
   940 		// Set address time
       
   941 		pMemAddr->SetTime( iTime );
       
   942 		// Set address module name
       
   943 		if ( pMemAddr->FindSetModuleName( &m_vDllLoadModList ) )
       
   944 		{
       
   945 			// Increment leaks in module once
       
   946 			if ( sModuleName.empty() )
       
   947 			{
       
   948 				if ( m_bSubtestOnGoing )
       
   949 					m_vDllLoadModListSubTest.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
       
   950 				else
       
   951 					m_vDllLoadModList.at( pMemAddr->GetDllLoadInfoIndex() ).iLeaks++;
       
   952 				// Set leak's module where it was located.
       
   953 				sModuleName = pMemAddr->GetModuleName();
       
   954 			}
       
   955 		}
       
   956 		// Add it to vector
       
   957 		m_vMemoryAddress.push_back( pMemAddr );
       
   958 	}
       
   959 	// If logging level is 0 Skip printing / locating code lines for call stack items.
       
   960 	if ( m_iLogLevel == 0 )
       
   961 		return true;
       
   962 	if ( m_pModules && vStrings.size() > 0 )
       
   963 	{
       
   964 		// Have we successfully located code line for memory address
       
   965 		bool bSuccesfullAddressToLine = false;
       
   966 		for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
       
   967 		{
       
   968 			int iIndexInDll = m_vMemoryAddress.at( x )->GetDllLoadInfoIndex();
       
   969 			if ( iIndexInDll != -1 )
       
   970 			{
       
   971 				// Dll module name from data file
       
   972 				string sDllName = m_vDllLoadModList.at( iIndexInDll ).sModuleName;
       
   973 				// Find module from project. These are read from makefiles.
       
   974 				for ( size_t y = 0; y < m_pModules->size() ; y++ )
       
   975 				{
       
   976 					// Module name from project data (makefiles)
       
   977 					string sModuleName = m_pModules->at( y )->GetBinaryName();
       
   978 					// If we find module from project ones, use it to located code line for memory address
       
   979 					// Note! dll names can be pretty messy i.e. DLL_LOAD 10281fc6.dll{000a0000}[10281fc6] 81d57b88 81e60a90
       
   980 					if ( sDllName.find( sModuleName ) != string::npos )
       
   981 					{
       
   982 						m_pModules->at( y )->AddressToLine( m_vMemoryAddress.at( x ) );
       
   983 						if ( ! bSuccesfullAddressToLine )
       
   984 						{
       
   985 							int iPPState = m_vMemoryAddress.at( x )->GetAddressToLineState();
       
   986 							if ( iPPState == CATMemoryAddress::EXACT || iPPState == CATMemoryAddress::FUNCTION )
       
   987 							{
       
   988 								bSuccesfullAddressToLine = true;
       
   989 								if ( m_bSubtestOnGoing )
       
   990 									m_iPinPointedSubTestLeaks++;
       
   991 								else
       
   992 									m_iPinPointedLeaks++;
       
   993 							}
       
   994 						}
       
   995 					}
       
   996 				}
       
   997 			}
       
   998 		}
       
   999 		// If rom/rofs specified we use it to try get binary and function names
       
  1000 		// for addresses currently out of process range.
       
  1001 		if ( m_pRomSymbol )
       
  1002 		{
       
  1003 			for( size_t x = 0; x < m_vMemoryAddress.size(); x++ )
       
  1004 			{
       
  1005 				if ( m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS
       
  1006 					|| m_vMemoryAddress.at(x)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_RANGE )
       
  1007 				{
       
  1008 					m_pRomSymbol->AddressToLine( m_vMemoryAddress.at(x) );
       
  1009 				}
       
  1010 			}
       
  1011 		}
       
  1012 	}
       
  1013 	// Print leak
       
  1014 	PrintMemLeak( sTime, sLeakSize, sLeakAddress, sModuleName);
       
  1015 	return true;
       
  1016 }
       
  1017 
       
  1018 // -----------------------------------------------------------------------------
       
  1019 // CATDatParser::PrintMemLeak
       
  1020 // -----------------------------------------------------------------------------
       
  1021 void CATDatParser::PrintMemLeak(const string& sTime,
       
  1022 							   const string& sLeakSize,
       
  1023 							   const string& sLeakAddr,
       
  1024 							   const string& sModuleName)
       
  1025 {
       
  1026 	LOG_FUNC_ENTRY("CATDatParser::PrintMemLeak");
       
  1027 	// Print header data of leak
       
  1028 	m_DataSaver.AddString("\nMemory leak ");
       
  1029 	m_DataSaver.AddInteger( m_iLeakNumber, true);
       
  1030 
       
  1031 	// Leak size
       
  1032 	m_DataSaver.AddString( " (" );
       
  1033 	m_DataSaver.AddInteger( _httoi( sLeakSize.c_str() ), true );
       
  1034 	m_DataSaver.AddString( " bytes) " );
       
  1035 
       
  1036 	// Leak address
       
  1037 	m_DataSaver.AddString("(0x");
       
  1038 	m_DataSaver.AddString( sLeakAddr.c_str(), true );
       
  1039 	m_DataSaver.AddString( ") " );
       
  1040 
       
  1041 	// Time
       
  1042 	m_DataSaver.AddString( sTime.c_str(), true );
       
  1043 	m_DataSaver.AddString( " " );
       
  1044 	
       
  1045 	// Module name
       
  1046 	m_DataSaver.AddString( sModuleName.c_str(), true );
       
  1047 	m_DataSaver.SaveCarbideDataHeader();
       
  1048 	
       
  1049 	// Add header line
       
  1050 	m_DataSaver.AddLineToLast();
       
  1051 
       
  1052 	// Print the call stack items
       
  1053 	for( size_t i = 0 ; i < m_vMemoryAddress.size() ; i++ )
       
  1054 	{
       
  1055 		// On log levels 1 & 2 we only print located code lines.
       
  1056 		#ifndef ADDR2LINE
       
  1057 		if( 
       
  1058 			( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
  1059 			&&
       
  1060 			( m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT
       
  1061 			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::FUNCTION )
       
  1062 			)
       
  1063 		{
       
  1064 			// Skips to next
       
  1065 			continue;
       
  1066 		}
       
  1067 		#endif
       
  1068 		#ifdef ADDR2LINE
       
  1069 		if( ( m_iLogLevel == 1 || m_iLogLevel == 2 )
       
  1070 			&& m_vMemoryAddress.at(i)->GetAddressToLineState() != CATMemoryAddress::EXACT )
       
  1071 		{
       
  1072 			// Skips to next
       
  1073 			continue;
       
  1074 		}
       
  1075 		#endif
       
  1076 		else if ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::OUT_OF_PROCESS )
       
  1077 		{
       
  1078 			// Is memory address out of modules range
       
  1079 			string sTemp;
       
  1080 			sTemp.append( m_vMemoryAddress.at(i)->GetAddressString() );
       
  1081 			sTemp.append( " Address out of process memory.");
       
  1082 			m_DataSaver.AddString( sTemp.c_str(), true );
       
  1083 			m_DataSaver.AddLineToLast();
       
  1084 			continue;
       
  1085 		}
       
  1086 		
       
  1087 		// Print memory address
       
  1088 		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetAddressString().c_str(), true );
       
  1089 
       
  1090 		// Space (only for console output)
       
  1091 		m_DataSaver.AddString( " " );
       
  1092 
       
  1093 		m_DataSaver.AddCarbideData( 
       
  1094 			NumberToHexString( m_vMemoryAddress.at(i)->GetOffSetFromModuleStart() ) );
       
  1095 
       
  1096 		// Module name
       
  1097 		m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetModuleName().c_str(), true );
       
  1098 
       
  1099 		// Print call stack memory address details depending on state of memory address
       
  1100 		switch( m_vMemoryAddress.at(i)->GetAddressToLineState() )
       
  1101 		{
       
  1102 			// Address outside of known processes
       
  1103 		case CATMemoryAddress::OUT_OF_PROCESS:
       
  1104 			m_DataSaver.AddLineToLast();
       
  1105 			break;
       
  1106 			// Address located outside of known modules symbols
       
  1107 		case CATMemoryAddress::OUT_OF_RANGE:
       
  1108 			m_DataSaver.AddString( " " );
       
  1109 			m_DataSaver.AddString( "???", true );
       
  1110 			m_DataSaver.AddLineToLast();
       
  1111 			break;
       
  1112 		// Symbol state is currently used when using rom symbol file.
       
  1113 		// From it we get module name & function name.
       
  1114 		case CATMemoryAddress::SYMBOL:
       
  1115 			m_DataSaver.AddString( " " );
       
  1116 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1117 			if ( ! m_vMemoryAddress.at( i )->GetFileName().empty() )
       
  1118 			{
       
  1119 				m_DataSaver.AddString( " (" );
       
  1120 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1121 				m_DataSaver.AddString( ")" );
       
  1122 			}
       
  1123 			m_DataSaver.AddLineToLast();
       
  1124 			break;
       
  1125 		// Lst & Map implementation
       
  1126 		#ifndef ADDR2LINE
       
  1127 		case CATMemoryAddress::FUNCTION:
       
  1128 		case CATMemoryAddress::EXACT:
       
  1129 			m_DataSaver.AddString( " " );
       
  1130 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1131 			// Small difference displaying details depending on build urel/udeb
       
  1132 			if ( m_eBuildType == CATProject::UREL )
       
  1133 			{
       
  1134 				// UREL
       
  1135 				// Set build info to data saver
       
  1136 				m_DataSaver.SetBuild( false );
       
  1137 				// urel = functionname: linenumber (filename)
       
  1138 				m_DataSaver.AddString( ": " );
       
  1139 				if (  m_vMemoryAddress.at(i)->GetFunctionLineNumber() != -1 )
       
  1140 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
       
  1141 				else if (  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1142 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1143 				m_DataSaver.AddString( " (" );
       
  1144 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1145 				m_DataSaver.AddString( ")" );
       
  1146 				m_DataSaver.AddLineToLast();
       
  1147 			}
       
  1148 			else
       
  1149 			{
       
  1150 				// UDEB
       
  1151 				// udeb = functionname: (filename:linenumber)
       
  1152 				m_DataSaver.AddString( " (" );
       
  1153 				m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1154 				m_DataSaver.AddString( ":" );
       
  1155 				if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1156 					m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1157 				else
       
  1158 					m_DataSaver.AddString( "???", true );
       
  1159 				m_DataSaver.AddString( ")" );
       
  1160 				m_DataSaver.AddLineToLast();
       
  1161 			}
       
  1162 			break;
       
  1163 		#endif
       
  1164 		// addr2line implementation (new).
       
  1165 		#ifdef ADDR2LINE
       
  1166 		case CATMemoryAddress::FUNCTION:
       
  1167 			m_DataSaver.AddString( " " );
       
  1168 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1169 			m_DataSaver.AddString( " (" );
       
  1170 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1171 			m_DataSaver.AddString( ":" );
       
  1172 			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1173 				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetFunctionLineNumber(), true );
       
  1174 			else
       
  1175 				m_DataSaver.AddString( "???", true );
       
  1176 			m_DataSaver.AddString( ")" );
       
  1177 			m_DataSaver.AddLineToLast();
       
  1178 			break;
       
  1179 		case CATMemoryAddress::EXACT:
       
  1180 			m_DataSaver.AddString( " " );
       
  1181 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFunctionName().c_str(), true );
       
  1182 			m_DataSaver.AddString( " (" );
       
  1183 			m_DataSaver.AddString( m_vMemoryAddress.at(i)->GetFileName().c_str(), true );
       
  1184 			m_DataSaver.AddString( ":" );
       
  1185 			if(  m_vMemoryAddress.at(i)->GetExactLineNumber() != -1 )
       
  1186 				m_DataSaver.AddInteger( m_vMemoryAddress.at(i)->GetExactLineNumber(), true );
       
  1187 			else
       
  1188 				m_DataSaver.AddString( "???", true );
       
  1189 			m_DataSaver.AddString( ")" );
       
  1190 			m_DataSaver.AddLineToLast();
       
  1191 			break;
       
  1192 		#endif
       
  1193 		} // End switch
       
  1194 		// On logging level 1 we only print one located code line
       
  1195 		#ifndef ADDR2LINE
       
  1196 		if ( m_iLogLevel == 1 && ( m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT ||
       
  1197 			m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::FUNCTION ) )
       
  1198 			break;
       
  1199 		#endif
       
  1200 		#ifdef ADDR2LINE
       
  1201 		if ( m_iLogLevel == 1 && m_vMemoryAddress.at(i)->GetAddressToLineState() == CATMemoryAddress::EXACT )
       
  1202 			break;
       
  1203 		#endif
       
  1204 	} // End call stack items loop
       
  1205 }
       
  1206 
       
  1207 // -----------------------------------------------------------------------------
       
  1208 // CATDatParser::SetInputFile
       
  1209 // -----------------------------------------------------------------------------
       
  1210 void CATDatParser::SetInputFile(const string& sInputFile)
       
  1211 {
       
  1212 	LOG_FUNC_ENTRY("CATDatParser::SetInputFile");
       
  1213 	m_sInputFile = sInputFile;
       
  1214 }
       
  1215 
       
  1216 // -----------------------------------------------------------------------------
       
  1217 // CATDatParser::SetOutputFile
       
  1218 // -----------------------------------------------------------------------------
       
  1219 void CATDatParser::SetOutputFile(const string& sOutpuFile)
       
  1220 {
       
  1221 	LOG_FUNC_ENTRY("CATDatParser::SetOutputFile");
       
  1222 	m_sOutputFile = sOutpuFile;
       
  1223 }
       
  1224 
       
  1225 // -----------------------------------------------------------------------------
       
  1226 // CATDatParser::SetRomSymbolFiles
       
  1227 // -----------------------------------------------------------------------------
       
  1228 void CATDatParser::SetRomSymbolFiles(const vector<string>& vRomSymbolFiles)
       
  1229 {
       
  1230 	LOG_FUNC_ENTRY("CATDatParser::SetRomSymbolFiles");
       
  1231 	m_vRomSymbolFiles = vRomSymbolFiles;
       
  1232 }
       
  1233 
       
  1234 // -----------------------------------------------------------------------------
       
  1235 // CATDatParser::SetLogLevel
       
  1236 // -----------------------------------------------------------------------------
       
  1237 void CATDatParser::SetLogLevel(int iLogLevel)
       
  1238 {
       
  1239 	LOG_FUNC_ENTRY("CATDatParser::SetLogLevel");
       
  1240 	m_iLogLevel = iLogLevel;
       
  1241 }
       
  1242 
       
  1243 // -----------------------------------------------------------------------------
       
  1244 // CATDatParser::GetLogLevel
       
  1245 // -----------------------------------------------------------------------------
       
  1246 int CATDatParser::GetLogLevel() const
       
  1247 {
       
  1248 	LOG_LOW_FUNC_ENTRY("CATDatParser::GetLogLevel");
       
  1249 	return m_iLogLevel;
       
  1250 }
       
  1251 
       
  1252 // -----------------------------------------------------------------------------
       
  1253 // CATDatParser::CleanMemoryAddresses
       
  1254 // -----------------------------------------------------------------------------
       
  1255 void CATDatParser::CleanMemoryAddresses()
       
  1256 {
       
  1257 	LOG_LOW_FUNC_ENTRY("CATDatParser::CleanMemoryAddresses");
       
  1258 	// Cleanup memory addressses.
       
  1259 	for( vector<CATMemoryAddress*>::iterator it = m_vMemoryAddress.begin(); it != m_vMemoryAddress.end(); it++ )
       
  1260 	{
       
  1261 		delete *it;
       
  1262 	}
       
  1263 	m_vMemoryAddress.clear();
       
  1264 }
       
  1265 
       
  1266 // -----------------------------------------------------------------------------
       
  1267 // CATDatParser::ConvertTimeToLocalTime
       
  1268 // -----------------------------------------------------------------------------
       
  1269 string CATDatParser::ConvertTimeToLocalTime( string sInputTime )
       
  1270 {
       
  1271 	LOG_LOW_FUNC_ENTRY("CATDatParser::ConvertTimeToLocalTime");
       
  1272 	//Is process end abnormal?
       
  1273 	if( sInputTime.compare( LABEL_ABNORMAL ) == 0 )
       
  1274 	{
       
  1275 		return string( AT_ANALYZE_ABNORMAL_EXIT );
       
  1276 	}
       
  1277 	else
       
  1278 	// Check that input time is at least 32-bit
       
  1279 	if( sInputTime.length() <= 8 )
       
  1280 	{
       
  1281 		sInputTime.clear();
       
  1282 		return sInputTime;
       
  1283 	}
       
  1284 
       
  1285 	string sTemp = sInputTime;
       
  1286 	const char* pTemp = sTemp.c_str();
       
  1287 
       
  1288 	// Are all characters hex
       
  1289 	for( unsigned int i = 0 ; i < sTemp.size() ; i++ )
       
  1290 	{
       
  1291 		if( !IsHexCharacter( (pTemp + i) ) )
       
  1292 		{
       
  1293 			return sInputTime;
       
  1294 		}
       
  1295 	}
       
  1296 	
       
  1297 	// Get LSB bits
       
  1298 	string sLsb;
       
  1299 	sLsb.append( sInputTime.substr( sInputTime.length()-8, sInputTime.length() ) );
       
  1300 	unsigned int iLsbTime = (unsigned int)_httoi( sLsb.c_str() );
       
  1301 
       
  1302 	// Get MSB bits
       
  1303     string sMsb;
       
  1304 	sMsb.append( sInputTime.substr( 0, sInputTime.length()-8 ) );
       
  1305 	unsigned int iMsbTime = (unsigned int)_httoi( sMsb.c_str() );
       
  1306 
       
  1307 	// Get time in microsecods
       
  1308 	long long sdf = iMsbTime * 0x100000000 + iLsbTime;
       
  1309 
       
  1310 	// Get original time (starting at year 1970 )
       
  1311 	long long llOrigTime = sdf;
       
  1312 
       
  1313 	// Get seconds
       
  1314 	sdf = ( sdf )/1000000;
       
  1315 		
       
  1316 	// Check that sdf contains some time value
       
  1317 	if( sdf <= 0)
       
  1318 	{
       
  1319 		// Error in time calculation
       
  1320 		// Return empty string
       
  1321 		sInputTime.clear();
       
  1322 		return sInputTime;
       
  1323 	}
       
  1324 
       
  1325 	// Original time after year 1970 in seconds
       
  1326 	long long llOrignTimeInSeconds = sdf;
       
  1327 	
       
  1328 	// Calculate new time which does not include millisecods
       
  1329 	long long llDiffTime = (llOrignTimeInSeconds * 1000000);
       
  1330 
       
  1331 	// Calculate time difference in milliseconds
       
  1332 	int llDiffTimeInMilliSecods = (int)( llOrigTime - llDiffTime )/1000;
       
  1333 	
       
  1334 	// Convert difference time to char
       
  1335 	char cDiffInMilliSeconds[20];
       
  1336     _itoa( llDiffTimeInMilliSecods, cDiffInMilliSeconds, 10 );
       
  1337 
       
  1338 	// Time info structure
       
  1339 	struct tm *timeinfo;
       
  1340 
       
  1341 	// Get local time
       
  1342 	timeinfo = localtime ( (time_t*) &sdf );
       
  1343 
       
  1344 	// Create string and append memory leak time to it
       
  1345 	string sTime;
       
  1346 	sTime.append( asctime( timeinfo ) );
       
  1347 
       
  1348 	// Remove last char of locale time string which is \n
       
  1349 	sTime.resize( (int)sTime.length()-1 );
       
  1350 	
       
  1351 	// Get last space index
       
  1352 	int iLastSpace = (int)sTime.find_last_of(" ");
       
  1353 
       
  1354 	// If last space index is valid
       
  1355 	if( iLastSpace <= (int)sTime.length() && iLastSpace > 0)
       
  1356 	{
       
  1357 		string sTempTime;
       
  1358 		// Append first part of original time string
       
  1359 		sTempTime.append( sTime.substr( 0, iLastSpace ) );
       
  1360 		
       
  1361 		// Append millisecods
       
  1362 		sTempTime.append( "." );
       
  1363 		sTempTime.append( cDiffInMilliSeconds );
       
  1364 
       
  1365 		// Append the rest of the original time string part
       
  1366 		sTempTime.append( sTime.substr( iLastSpace, sTime.length()));
       
  1367 
       
  1368 		// Clear original and append new time string which includes millisecods
       
  1369 		sTime.clear();
       
  1370 		sTime.append( sTempTime );
       
  1371 	}
       
  1372 
       
  1373 	// Return memory leak time
       
  1374 	return sTime.c_str();
       
  1375 }
       
  1376 
       
  1377 bool CATDatParser::CreateWinscwModule( const string& sBinaryName )
       
  1378 {
       
  1379 	LOG_FUNC_ENTRY( "CATDatParser::CreateWinscwModule" );
       
  1380 	// Is module already created?
       
  1381 	for( vector<CATModule2*>::iterator it = m_pModules->begin(); it != m_pModules->end(); it++ )
       
  1382 	{
       
  1383 		if ( _stricmp( sBinaryName.c_str(), (*it)->GetBinaryName().c_str() ) == 0 )
       
  1384 			return true;
       
  1385 	}
       
  1386 	// No create new one and set its values.
       
  1387 	CATModule2* mod = new CATModule2();
       
  1388 	mod->SetTarget( RemovePathAndExt( sBinaryName, true ) );
       
  1389 	mod->SetRequestedTargetExt( GetExtension( sBinaryName ) );
       
  1390 	mod->SetReleasePath( string( "\\epoc32\\release" ) );
       
  1391 	if ( m_eBuildType == CATProject::UDEB )
       
  1392 		mod->SetFullVariantPath( string( "winscw\\udeb" ) );
       
  1393 	else
       
  1394 		mod->SetFullVariantPath( string( "winscw\\urel" ) );
       
  1395 	mod->SetVariantPlatform( string( "winscw" ) );
       
  1396 	m_pModules->push_back( mod );
       
  1397 	return true;
       
  1398 }
       
  1399 
       
  1400 // -----------------------------------------------------------------------------
       
  1401 // CATDatParser::ParseStringToVector
       
  1402 // -----------------------------------------------------------------------------
       
  1403 vector<string> CATDatParser::ParseStringToVector( const string& sInput, char separator )
       
  1404 {
       
  1405 	LOG_LOW_FUNC_ENTRY("CATDatParser::ParseStringToVector");
       
  1406 	string sString(sInput);
       
  1407 	// Elements vector
       
  1408 	vector<string> vStrings;
       
  1409 	size_t iPos = sString.find( separator );
       
  1410 	// If can not find it return vector with just one element
       
  1411 	if ( iPos == string::npos )
       
  1412 	{
       
  1413 		// Don't add empty item into vector.
       
  1414 		if ( sString.size() > 0 )
       
  1415 			vStrings.push_back( sString );
       
  1416 		return vStrings;
       
  1417 	}
       
  1418 	// Loop elements
       
  1419 	while( iPos != string::npos )
       
  1420 	{
       
  1421 		string sElement = sString.substr(0, iPos);
       
  1422 		vStrings.push_back( sElement );
       
  1423 		sString.erase(0, iPos +1 );
       
  1424 		iPos = sString.find( separator );
       
  1425 	}
       
  1426 	// Add last element if any
       
  1427 	if ( sString.size() > 0 )
       
  1428 		vStrings.push_back( sString );
       
  1429 	// Return elements
       
  1430 	return vStrings;
       
  1431 }
       
  1432 
       
  1433 // -----------------------------------------------------------------------------
       
  1434 // CATDatParser::FindModuleUsingAddress
       
  1435 // Function finds module using given address.
       
  1436 // -----------------------------------------------------------------------------
       
  1437 int CATDatParser::FindModuleUsingAddress( unsigned long iAddress ) const
       
  1438 {
       
  1439 	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingAddress");
       
  1440 	int iRet = -1;
       
  1441 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1442 	{
       
  1443 		// Is address between start and end address?
       
  1444 		if( iAddress > m_vDllLoadModList[i].iStartAddress && iAddress < m_vDllLoadModList[i].iEndAddress )
       
  1445 		{
       
  1446 			iRet = i;
       
  1447 			break;
       
  1448 		}	
       
  1449 	}
       
  1450 	return iRet;
       
  1451 }
       
  1452 
       
  1453 // -----------------------------------------------------------------------------
       
  1454 // CATDatParser::FindModuleUsingPID
       
  1455 // Function finds module using module id.
       
  1456 // -----------------------------------------------------------------------------
       
  1457 /*
       
  1458 int CATDatParser::FindModuleUsingPID( unsigned long iPID ) const
       
  1459 {
       
  1460 	LOG_FUNC_ENTRY("CATDatParser::FindModuleUsingPID");
       
  1461 
       
  1462 	int iRet = -1;
       
  1463 
       
  1464 	// Change module name characters to lowercase
       
  1465 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1466 	{
       
  1467 		if( m_vDllLoadModList[i].iPID == iPID )
       
  1468 		{
       
  1469 			iRet = i;
       
  1470 			break;
       
  1471 		}	
       
  1472 	}
       
  1473 	return iRet;
       
  1474 }
       
  1475 */
       
  1476 // -----------------------------------------------------------------------------
       
  1477 // CATDatParser::FindModuleUsingName
       
  1478 // Function finds module using module name.
       
  1479 // -----------------------------------------------------------------------------
       
  1480 int CATDatParser::FindModuleUsingName( const char* pModName )
       
  1481 {
       
  1482 	LOG_LOW_FUNC_ENTRY("CATDatParser::FindModuleUsingName");
       
  1483 
       
  1484 	// Mod name empty?
       
  1485 	if( pModName == NULL || *pModName == 0 )
       
  1486 		return -1;
       
  1487 
       
  1488 	int iRet = -1;
       
  1489 	string sModName( pModName );
       
  1490 	// Change module name characters to lowercase
       
  1491 	ChangeToLower( sModName );
       
  1492 	// Remove variant marks (dots)
       
  1493 	RemoveAllAfterDotIfTwoDots( sModName);
       
  1494 	for( unsigned int i = 0 ; i < m_vDllLoadModList.size() ; i++ )
       
  1495 	{
       
  1496 		string sTemp( m_vDllLoadModList[i].sModuleName );
       
  1497 		ChangeToLower( sTemp );
       
  1498 		// Remove variant marks (dots)
       
  1499 		RemoveAllAfterDotIfTwoDots( sTemp );
       
  1500 		if( sTemp.find( sModName ) != string::npos )
       
  1501 		{
       
  1502 			iRet = i;
       
  1503 			break;
       
  1504 		}	
       
  1505 	}
       
  1506 	return iRet;
       
  1507 }
       
  1508 
       
  1509 // -----------------------------------------------------------------------------
       
  1510 // CATDatParser::SetPrintFlag
       
  1511 // -----------------------------------------------------------------------------
       
  1512 void CATDatParser::SetPringFlag( bool bPrintFlag )
       
  1513 {
       
  1514 	LOG_FUNC_ENTRY("CATDatParser::SetPringFlag");
       
  1515 	m_DataSaver.SetPrintFlag( bPrintFlag );
       
  1516 }
       
  1517 // -----------------------------------------------------------------------------
       
  1518 // CATDatParser::SetOffSet
       
  1519 // -----------------------------------------------------------------------------
       
  1520 void CATDatParser::SetOffSet( int iOffSet )
       
  1521 {
       
  1522 	LOG_FUNC_ENTRY("CATDatParser::SetOffSet");
       
  1523 	m_iOffSet = iOffSet;
       
  1524 }
       
  1525 
       
  1526 // -----------------------------------------------------------------------------
       
  1527 // CATDatParser::GetOffSet
       
  1528 // -----------------------------------------------------------------------------
       
  1529 int CATDatParser::GetOffSet( ) const
       
  1530 {
       
  1531 	LOG_LOW_FUNC_ENTRY("CATDatParser::GetOffSet");
       
  1532 	return m_iOffSet;
       
  1533 }
       
  1534 
       
  1535 // -----------------------------------------------------------------------------
       
  1536 // Set project platform.
       
  1537 // -----------------------------------------------------------------------------
       
  1538 void CATDatParser::SetProjectPlatform( const string& sPlatform )
       
  1539 {
       
  1540 	LOG_FUNC_ENTRY("CATDatParser::SetProjectPlatform");
       
  1541 	m_sProjectPlatform = sPlatform;
       
  1542 
       
  1543 	// Check that platform not empty before determing platform from it.
       
  1544 	if ( sPlatform.empty() )
       
  1545 		return;
       
  1546 
       
  1547 	// Set functions offset in mapfiles correct (depending on platform).
       
  1548 	if ( _stricmp( sPlatform.c_str(), "armv5" ) == 0 )
       
  1549 	{
       
  1550 		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_ARMV5;
       
  1551 	}
       
  1552 	else if ( _stricmp( sPlatform.c_str(), "winscw" ) == 0 )
       
  1553 	{
       
  1554 		m_iOffSet = FUNCTIONS_OFFSET_IN_MAP_FILE_WINSCW;
       
  1555 	}
       
  1556 	else if ( _stricmp( sPlatform.c_str(), "gcce" ) == 0 )
       
  1557 	{
       
  1558 		m_iOffSet = FUNCTIONS_OFFSET_IN_GCCE;
       
  1559 	}
       
  1560 	else
       
  1561 	{
       
  1562 		LOG_STRING( AT_MSG << "Error, cannot set function's offset in map file, invalid platform: " << sPlatform );
       
  1563 	}
       
  1564 }
       
  1565 
       
  1566 // -----------------------------------------------------------------------------
       
  1567 // Set projects build type. Use enumeration defined in CATProject.
       
  1568 // -----------------------------------------------------------------------------
       
  1569 void CATDatParser::SetProjectBuildType( int eBuildType )
       
  1570 {
       
  1571 	LOG_FUNC_ENTRY("CATDatParser::SetProjectBuildType");
       
  1572 	m_eProjectBuildType = eBuildType;
       
  1573 }
       
  1574 
       
  1575 //EOF