analyzetool/commandlineengine/src/CATDataSaver.cpp
changeset 22 a009639409f5
equal deleted inserted replaced
17:67c6ff54ec25 22:a009639409f5
       
     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:  Definitions for the class CATDataSaver.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "../inc/catdatasaver.h"
       
    20 
       
    21 #include <xercesc/util/OutOfMemoryException.hpp>
       
    22 
       
    23 #if defined(XERCES_NEW_IOSTREAMS)
       
    24 #include <iostream>
       
    25 #else
       
    26 #include <iostream.h>
       
    27 #endif
       
    28 
       
    29 // Line feed char sequence used in XML report
       
    30 wchar_t AT_XML_LINEFEEDS[3] = L"\r\n";
       
    31 
       
    32 // -----------------------------------------------------------------------------
       
    33 // CATDataSaver::CATDataSaver
       
    34 // Constructor.
       
    35 // -----------------------------------------------------------------------------
       
    36 CATDataSaver::CATDataSaver( void )
       
    37 {
       
    38 	LOG_FUNC_ENTRY("CATDataSaver::CATDataSaver");
       
    39 	m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
       
    40 	m_bPrintImmediately = true;
       
    41 	m_bXMLInitOk = false;
       
    42 	m_bUdebBuild = true;
       
    43 
       
    44 	m_iRunNumber = 1;
       
    45 
       
    46 	m_pDomDoc = NULL;
       
    47 	m_pRootElem = NULL;
       
    48 	m_Serializer = NULL;
       
    49 	m_pCurrentLeakElem = NULL;
       
    50 	m_pRunElement = NULL;
       
    51 	m_pMemoryLeaks = NULL;
       
    52 	m_pHandleLeaks = NULL;
       
    53 	m_pCurrentSubTestElem = NULL;
       
    54 	m_pSubtestMemoryLeaks = NULL;
       
    55 }
       
    56 
       
    57 // -----------------------------------------------------------------------------
       
    58 // CATDataSaver::~CATDataSaver
       
    59 // Destructor.
       
    60 // -----------------------------------------------------------------------------
       
    61 CATDataSaver::~CATDataSaver(void)
       
    62 {
       
    63 	LOG_FUNC_ENTRY("CATDataSaver::~CATDataSaver");
       
    64 	if( m_bXMLInitOk )
       
    65 	{
       
    66 		if( m_Serializer )
       
    67 			delete m_Serializer;
       
    68 
       
    69 		m_pDomDoc->release();
       
    70 		xercesc::XMLPlatformUtils::Terminate();
       
    71 	}
       
    72 }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // CATDataSaver::SaveLinesToFile
       
    76 // Gets logging level.
       
    77 // -----------------------------------------------------------------------------
       
    78 void CATDataSaver::SaveLinesToFile( const char* pFileName, int iDataToSave )
       
    79 {
       
    80 	LOG_FUNC_ENTRY("CATDataSaver::SaveLinesToFile");
       
    81 
       
    82 	// Nothing to print?
       
    83 	if( m_vLines.empty() )
       
    84 	{
       
    85 		printf( "No output data." );
       
    86 		return;
       
    87 	}
       
    88 	if( iDataToSave != XML_DATA )
       
    89 	{
       
    90 		ofstream out( pFileName );
       
    91 
       
    92 		if( !out.good() )
       
    93 		{
       
    94 			printf( "Can not open file: %s\n", pFileName );
       
    95 			return;
       
    96 		}
       
    97 		switch( iDataToSave )
       
    98 		{
       
    99 			case TEXT_DATA:
       
   100 				for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
       
   101 				{
       
   102 					out << m_vLines[i].c_str();
       
   103 				}
       
   104 			break;
       
   105 		}
       
   106 		out.close();
       
   107 	}
       
   108 	else
       
   109 	{
       
   110 		if( m_bXMLInitOk )
       
   111 		{
       
   112 			xercesc::XMLFormatTarget* myFormTarget = NULL;
       
   113 			try
       
   114 			{
       
   115 				// Create format
       
   116 				myFormTarget = new xercesc::LocalFileFormatTarget( pFileName );
       
   117 				
       
   118 				// Set line-feeds to dom writer
       
   119 				m_Serializer->setNewLine( AT_XML_LINEFEEDS );
       
   120 				
       
   121 				// Set human-readable property. Note! Api already changed in >2.7
       
   122 				// so this will cause error/problems if linked to newer library.
       
   123 				m_Serializer->setFeature( xercesc::XMLUni::fgDOMWRTFormatPrettyPrint, true );
       
   124 				
       
   125 				// Write document
       
   126 				m_Serializer->writeNode(myFormTarget, *m_pDomDoc);
       
   127 			}
       
   128 			catch(...)
       
   129 			{
       
   130 				printf( "Can not save output file: %s.", pFileName );
       
   131 			}
       
   132 			if( myFormTarget )
       
   133 				delete myFormTarget; //lint !e118
       
   134 		}
       
   135 	}
       
   136 }
       
   137 
       
   138 // -----------------------------------------------------------------------------
       
   139 // CATDataSaver::PrintLinesToScreen
       
   140 // Prints all saved lines to screen.
       
   141 // -----------------------------------------------------------------------------
       
   142 void CATDataSaver::PrintLinesToScreen( void )
       
   143 {
       
   144 	LOG_FUNC_ENTRY("CATDataSaver::PrintLinesToScreen");
       
   145 	// Nothing to print?
       
   146 	if( m_vLines.empty() )
       
   147 	{
       
   148 		printf( "No output data." );
       
   149 		return;
       
   150 	}
       
   151 	for( int i = 0 ; i < (int)m_vLines.size() ; i++ )
       
   152 	{
       
   153 		printf( m_vLines[i].c_str() );	
       
   154 	}
       
   155 }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CATDataSaver::AddLineToFirst
       
   159 // Adds saved line to first in database.
       
   160 // -----------------------------------------------------------------------------
       
   161 void CATDataSaver::AddLineToFirst( void )
       
   162 {
       
   163 	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToFirst");
       
   164 	m_sLine.append( "\n" );
       
   165 	m_vLines.insert( m_vLines.begin(), m_sLine );
       
   166 	m_sLine.clear();
       
   167 }
       
   168 
       
   169 // -----------------------------------------------------------------------------
       
   170 // CATDataSaver::AddLineToLast
       
   171 // Adds saved line to last in database.
       
   172 // -----------------------------------------------------------------------------
       
   173 void CATDataSaver::AddLineToLast()
       
   174 {
       
   175 	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddLineToLast");
       
   176 	m_sLine.append( "\n" );
       
   177 	
       
   178 	string sTempDataLine;
       
   179 
       
   180 	m_vLines.push_back( m_sLine );
       
   181 
       
   182 	SaveXML( m_sCarbideDataLine, ITEM );
       
   183 
       
   184 	if( m_bPrintImmediately )
       
   185 	{
       
   186 		printf( m_sLine.c_str() );
       
   187 	}
       
   188 
       
   189 	m_sCarbideDataLine.clear();
       
   190 	m_sLine.clear();
       
   191 }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CATDataSaver::AddString
       
   195 // Adds string to current line.
       
   196 // -----------------------------------------------------------------------------
       
   197 void CATDataSaver::AddString( const char* pData, bool bSaveCarbideData )
       
   198 {
       
   199 	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddString");
       
   200 	m_sLine.append( pData );
       
   201 
       
   202 	if( bSaveCarbideData )
       
   203 	{
       
   204 		m_sCarbideDataLine.append( pData );
       
   205 		m_sCarbideDataLine.append(";");
       
   206 	}
       
   207 }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CATDataSaver::AddInteger
       
   211 // Converts integer to string and adds it to current line.
       
   212 // -----------------------------------------------------------------------------
       
   213 void CATDataSaver::AddInteger( int iValue, bool bSaveCarbideData )
       
   214 {
       
   215 	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddInteger");
       
   216 	char cTemp[128];
       
   217 	string sValue( itoa( iValue, cTemp, 10 ) );
       
   218 	m_sLine.append( sValue );
       
   219 
       
   220 	if( bSaveCarbideData )
       
   221 	{
       
   222 		m_sCarbideDataLine.append( sValue );
       
   223 		m_sCarbideDataLine.append(";");
       
   224 	}
       
   225 }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CATDataSaver::SetLoggingLevel
       
   229 // Sets logging level.
       
   230 // -----------------------------------------------------------------------------
       
   231 void CATDataSaver::SetLoggingLevel( int iLoggingLevel )
       
   232 {
       
   233 	LOG_FUNC_ENTRY("CATDataSaver::SetLoggingLevel");
       
   234 	// Check that new logging level is valid 
       
   235 	// Acceptable values are between MIN_LOGGING_LEVEL and 
       
   236     // MAX_LOGGING_LEVEL including them
       
   237 	if( iLoggingLevel >= MIN_LOGGING_LEVEL && iLoggingLevel <= MAX_LOGGING_LEVEL )
       
   238 	{
       
   239 		m_iLoggingLevel = iLoggingLevel;
       
   240 	}
       
   241 	else
       
   242 	{
       
   243 		// New logging level value is invalid => set default logging level
       
   244 		m_iLoggingLevel = DEFAULT_LOGGING_LEVEL;
       
   245 	}
       
   246 }
       
   247 
       
   248 // -----------------------------------------------------------------------------
       
   249 // CATDataSaver::GetLoggingLevel
       
   250 // Gets logging level.
       
   251 // -----------------------------------------------------------------------------
       
   252 int CATDataSaver::GetLoggingLevel( void )
       
   253 {
       
   254 	LOG_LOW_FUNC_ENTRY("CATDataSaver::GetLoggingLevel");
       
   255 	return m_iLoggingLevel;
       
   256 }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CATDataSaver::SetPrintFlag
       
   260 // Sets print immediately flag.
       
   261 // -----------------------------------------------------------------------------
       
   262 void CATDataSaver::SetPrintFlag( bool bPrintImmediately )
       
   263 {
       
   264 	LOG_FUNC_ENTRY("CATDataSaver::SetPrintFlag");
       
   265 	m_bPrintImmediately = bPrintImmediately;
       
   266 }
       
   267 
       
   268 // -----------------------------------------------------------------------------
       
   269 // CATDataSaver::SaveCarbideDataHeader
       
   270 // Sets data header for Carbide data.
       
   271 // -----------------------------------------------------------------------------
       
   272 void CATDataSaver::SaveCarbideDataHeader( void )
       
   273 {
       
   274 	LOG_FUNC_ENTRY("CATDataSaver::SaveCarbideDataHeader");
       
   275 	SaveXML( m_sCarbideDataLine, LEAK );
       
   276 	m_sCarbideDataLine.clear();
       
   277 }
       
   278 
       
   279 // -----------------------------------------------------------------------------
       
   280 // CATDataSaver::InitXML
       
   281 // Initializes xerces xml parser.
       
   282 // -----------------------------------------------------------------------------
       
   283 bool CATDataSaver::InitXML( void )
       
   284 {
       
   285 	LOG_FUNC_ENTRY("CATDataSaver::InitXML");
       
   286 	try 
       
   287 	{
       
   288 		xercesc::XMLPlatformUtils::Initialize();
       
   289 	}
       
   290 	catch ( ... )//(const XMLException& toCatch) 
       
   291 	{
       
   292 		// Do your failure processing here
       
   293 		printf("XML initialization failed.\n");
       
   294 		return false;
       
   295 	}
       
   296 	// Error code.
       
   297 	int errorCode = 0;
       
   298 	// getDomIMplementation returns null if source has none.
       
   299 	xercesc::DOMImplementation* impl = xercesc::DOMImplementationRegistry::getDOMImplementation(L"Core");
       
   300 	if (impl != NULL)
       
   301     {
       
   302 		// Create new DOMWriter.
       
   303 		m_Serializer = ((xercesc::DOMImplementationLS*)impl)->createDOMWriter();
       
   304 		// New document.
       
   305         try
       
   306         {
       
   307 			m_pDomDoc = impl->createDocument(
       
   308                         0,                    // Root element namespace URI.
       
   309                         L"results",         // Root element name
       
   310                         0);                   // Document type object (DTD).
       
   311 
       
   312             m_pRootElem = m_pDomDoc->getDocumentElement();
       
   313         }
       
   314         catch (const xercesc::OutOfMemoryException&)
       
   315         {
       
   316             XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
       
   317             errorCode = 5;
       
   318         }
       
   319         catch (const xercesc::DOMException& e)
       
   320         {
       
   321             XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
       
   322             errorCode = 2;
       
   323         }
       
   324         catch (...)
       
   325         {
       
   326             XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
       
   327             errorCode = 3;
       
   328         }
       
   329     }  // (inpl != NULL)
       
   330     else
       
   331     {
       
   332         XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
       
   333         errorCode = 4;
       
   334     }
       
   335 	if( !errorCode )
       
   336 	{
       
   337 		m_bXMLInitOk = true;
       
   338 		return true;
       
   339 	}
       
   340 	else
       
   341 	{
       
   342 		return false;
       
   343 	}
       
   344 }
       
   345 
       
   346 // -----------------------------------------------------------------------------
       
   347 // CATDataSaver::WCharToChar
       
   348 // Converts wchar_t* -> char*.
       
   349 // -----------------------------------------------------------------------------
       
   350 void CATDataSaver::WCharToChar( string& sInput, const WCHAR* Source )
       
   351 {
       
   352 	LOG_LOW_FUNC_ENTRY("CATDataSaver::WCharToChar");
       
   353 	if( !Source )
       
   354 		return;
       
   355     int i = 0;
       
   356 
       
   357     while( Source[i] != '\0' )
       
   358     {
       
   359 		char c = (CHAR)Source[i];
       
   360 		sInput.append( &c, 1 );
       
   361         ++i;
       
   362     }
       
   363 }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // CATDataSaver::CharToWChar
       
   367 // Converts char* -> wchar_t*.
       
   368 // -----------------------------------------------------------------------------
       
   369 LPWSTR CATDataSaver::CharToWChar( const char* str )
       
   370 {
       
   371 	LOG_LOW_FUNC_ENTRY("CATDataSaver::CharToWChar");
       
   372     LPWSTR out = NULL;
       
   373     if( str != NULL )
       
   374     {
       
   375         int in_len = (int)strlen( str );
       
   376         int out_len = MultiByteToWideChar(CP_ACP, 0, str, in_len, NULL, 0) + 2;
       
   377         out = new WCHAR[out_len];
       
   378 
       
   379         if (out)
       
   380         {
       
   381             memset(out, 0x00, sizeof(WCHAR)*out_len);
       
   382             MultiByteToWideChar(CP_ACP, 0, str, in_len, out, in_len);
       
   383         }
       
   384     }
       
   385     return out;
       
   386 }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CATDataSaver::SaveXML
       
   390 // Writes data to xml tree.
       
   391 // -----------------------------------------------------------------------------
       
   392 void CATDataSaver::SaveXML( string sInput, int iElementType )
       
   393 {
       
   394 	LOG_FUNC_ENTRY("CATDataSaver::SaveXML");
       
   395 	// Variables ok?
       
   396 	if( sInput.empty() || m_pDomDoc == NULL )
       
   397 	{
       
   398 		return;
       
   399 	}
       
   400 	try
       
   401 	{
       
   402 		switch( iElementType )
       
   403 		{
       
   404 			case RESULT:
       
   405 			{
       
   406 				// Print number of runs
       
   407 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   408 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   409 				m_pRootElem->setAttribute( L"runs", (const LPWSTR)wTemp );
       
   410 
       
   411 				// Print failed runs
       
   412 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   413 				if( wTemp )
       
   414 					delete[] wTemp;
       
   415 				wTemp = CharToWChar( sTemp.c_str() );
       
   416 				m_pRootElem->setAttribute( L"failed", (const LPWSTR)wTemp );
       
   417 				if( wTemp )
       
   418 					delete[] wTemp;
       
   419 			}
       
   420 			break;
       
   421 			case RUN:
       
   422 			{
       
   423 				if( m_pRootElem == NULL )
       
   424 					return;
       
   425 				xercesc::DOMElement* runElem = m_pDomDoc->createElement( L"run" );
       
   426 				m_pRootElem->appendChild( runElem );
       
   427 
       
   428 				// Reset handle leaks.
       
   429 				m_pHandleLeaks = NULL;
       
   430 
       
   431 				// Print start time
       
   432 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   433 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   434 				runElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
       
   435 				runElem->setAttribute( L"end_time", NULL );
       
   436 				if( wTemp )
       
   437 					delete[] wTemp;
       
   438 
       
   439 				// Print build target
       
   440 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   441 				wTemp = CharToWChar( sTemp.c_str() );
       
   442 				runElem->setAttribute( L"build_target", (const LPWSTR)wTemp );
       
   443 				if( wTemp )
       
   444 					delete[] wTemp;
       
   445 
       
   446 				// Print process name
       
   447 				wTemp = CharToWChar( sInput.c_str() );
       
   448 				runElem->setAttribute( L"process_name", (const LPWSTR)wTemp );
       
   449 
       
   450 				m_pRunElement = runElem;
       
   451 
       
   452 				char cTemp[128];
       
   453 				if( wTemp )
       
   454 					delete[] wTemp;
       
   455 				wTemp = CharToWChar( itoa( m_iRunNumber, cTemp, 10 ) );
       
   456 				runElem->setAttribute( L"id", (const LPWSTR)wTemp );
       
   457 				m_iRunNumber++;
       
   458 				if( wTemp )
       
   459 					delete[] wTemp;
       
   460 			}
       
   461 			break;
       
   462 			case LEAK:
       
   463 			{
       
   464 				m_pCurrentLeakElem = m_pDomDoc->createElement( L"leak" );
       
   465 
       
   466 
       
   467 				if( m_pCurrentLeakElem == NULL || m_pRunElement == NULL )
       
   468 					return;
       
   469 
       
   470 				// Sub test?
       
   471 				if( m_pCurrentSubTestElem )
       
   472 					m_pCurrentSubTestElem->appendChild( m_pCurrentLeakElem );
       
   473 				else
       
   474 					m_pRunElement->appendChild( m_pCurrentLeakElem );
       
   475 
       
   476 				// Print leak ID
       
   477 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   478 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   479 				m_pCurrentLeakElem->setAttribute( L"id", (const LPWSTR)wTemp );
       
   480 
       
   481 				// Print leak size
       
   482 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   483 				if( wTemp )
       
   484 					delete[] wTemp;
       
   485 				wTemp = CharToWChar( sTemp.c_str() );
       
   486 				m_pCurrentLeakElem->setAttribute( L"size", (const LPWSTR)wTemp );
       
   487 
       
   488 				// Print leak address
       
   489 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   490 				if( wTemp )
       
   491 					delete[] wTemp;
       
   492 				wTemp = CharToWChar( sTemp.c_str() );
       
   493 				m_pCurrentLeakElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
       
   494 
       
   495 				// Print leak time
       
   496 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   497 				if( wTemp )
       
   498 					delete[] wTemp;
       
   499 				wTemp = CharToWChar( sTemp.c_str() );
       
   500 				m_pCurrentLeakElem->setAttribute( L"time", (const LPWSTR)wTemp );
       
   501 
       
   502 				// Print leak module
       
   503 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   504 				if( wTemp )
       
   505 					delete[] wTemp;
       
   506 				wTemp = CharToWChar( sTemp.c_str() );
       
   507 				m_pCurrentLeakElem->setAttribute( L"module", (const LPWSTR)wTemp );
       
   508 				if( wTemp )
       
   509 					delete[] wTemp;
       
   510 			}
       
   511 			break;
       
   512 			case ITEM:
       
   513 			{
       
   514 				xercesc::DOMNode* callstackNode = NULL;
       
   515 
       
   516 				xercesc::DOMElement* callstackElem = NULL;
       
   517 
       
   518 				if( m_pCurrentLeakElem  == NULL )
       
   519 					return;
       
   520 
       
   521 				// Print module name
       
   522 				if( !m_pCurrentLeakElem->hasChildNodes() )
       
   523 				{
       
   524 					callstackElem = m_pDomDoc->createElement( L"callstack" );
       
   525 					m_pCurrentLeakElem->appendChild( callstackElem );
       
   526 					callstackNode = callstackElem;
       
   527 				}
       
   528 				else
       
   529 				{
       
   530 					callstackNode = m_pCurrentLeakElem->getFirstChild();
       
   531 				}
       
   532 
       
   533 				// Add callstack item
       
   534 				xercesc::DOMElement* itemElem = m_pDomDoc->createElement( L"item" );
       
   535 				callstackNode->appendChild( itemElem );
       
   536 
       
   537 				// Print memory address name
       
   538 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   539 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   540 
       
   541 				itemElem->setAttribute( L"memaddress", (const LPWSTR)wTemp );
       
   542 
       
   543 				// Print calculated memory address
       
   544 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   545 				if( wTemp )
       
   546 					delete[] wTemp;
       
   547 				wTemp = CharToWChar( sTemp.c_str() );
       
   548 
       
   549 				itemElem->setAttribute( L"calc_addr", (const LPWSTR)wTemp );
       
   550 
       
   551 				// Print module name
       
   552 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   553 				if( wTemp )
       
   554 					delete[] wTemp;
       
   555 				wTemp = CharToWChar( sTemp.c_str() );
       
   556 
       
   557 				itemElem->setAttribute( L"module", (const LPWSTR)wTemp );
       
   558 
       
   559 				// Print function name
       
   560 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   561 				if( wTemp )
       
   562 					delete[] wTemp;
       
   563 				wTemp = CharToWChar( sTemp.c_str() );
       
   564 
       
   565 				itemElem->setAttribute( L"function", (const LPWSTR)wTemp );
       
   566 
       
   567 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   568 
       
   569 				// Print function line from urel build
       
   570 				if( !m_bUdebBuild )
       
   571 				{
       
   572 					if( wTemp )
       
   573 						delete[] wTemp;
       
   574 					wTemp = CharToWChar( sTemp.c_str() );
       
   575 					itemElem->setAttribute( L"function_line", (const LPWSTR)wTemp );
       
   576 					sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   577 				}
       
   578 
       
   579 				// Print file name
       
   580 				if( wTemp )
       
   581 					delete[] wTemp;
       
   582 				// Erase if path found from sTemp.
       
   583 				if ( sTemp.rfind( "/" ) != string::npos )
       
   584 				{
       
   585 					sTemp.erase(0, sTemp.rfind( "/" )+1 );
       
   586 				}
       
   587 				if ( sTemp.rfind( "\\" ) != string::npos )
       
   588 				{
       
   589 					sTemp.erase(0, sTemp.rfind( "\\" )+1 );
       
   590 				}
       
   591 				wTemp = CharToWChar( sTemp.c_str() );
       
   592 
       
   593 				itemElem->setAttribute( L"file", (const LPWSTR)wTemp );
       
   594 
       
   595 				// Print line of file
       
   596 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   597 				if( wTemp )
       
   598 					delete[] wTemp;
       
   599 				wTemp = CharToWChar( sTemp.c_str() );
       
   600 
       
   601 				if( m_bUdebBuild )
       
   602 					itemElem->setAttribute( L"line", (const LPWSTR)wTemp );
       
   603 				if( wTemp )
       
   604 					delete[] wTemp;
       
   605 			}
       
   606 			break;
       
   607 			case RUN_END:
       
   608 			{
       
   609 				if( m_pRunElement == NULL )
       
   610 					return;
       
   611 				const LPWSTR wTemp = CharToWChar( sInput.c_str() );
       
   612 				m_pRunElement->setAttribute( L"end_time", wTemp );
       
   613 				if( wTemp )
       
   614 					delete[] wTemp;
       
   615 			}
       
   616 			break;
       
   617 			case ERROR_IN_RUN:
       
   618 			{
       
   619 				if( m_pRunElement == NULL )
       
   620 					return;
       
   621 				// Add error item
       
   622 				xercesc::DOMElement* errorElem = m_pDomDoc->createElement( L"error" );
       
   623 				m_pRunElement->appendChild( errorElem );
       
   624 
       
   625 				// Print error code
       
   626 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   627 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   628 				errorElem->setAttribute( L"code", (const LPWSTR)wTemp );
       
   629 
       
   630 				// Print error time
       
   631 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   632 				if( wTemp )
       
   633 					delete[] wTemp;
       
   634 				wTemp = CharToWChar( sTemp.c_str() );
       
   635 				errorElem->setAttribute( L"time", (const LPWSTR)wTemp );
       
   636 				if( wTemp )
       
   637 					delete[] wTemp;
       
   638 			}
       
   639 			break;
       
   640 			case MEM_LEAKS:
       
   641 			{
       
   642 				if( m_pRunElement == NULL )
       
   643 					return;
       
   644 				xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
       
   645 				m_pRunElement->appendChild( memoryLeaksElement );
       
   646 				m_pMemoryLeaks = memoryLeaksElement;
       
   647 
       
   648 				// Print number of leaks
       
   649 				LPWSTR wTemp = CharToWChar( sInput.c_str() );
       
   650 				memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
       
   651 				if( wTemp )
       
   652 					delete[] wTemp;
       
   653 			}
       
   654 			break;
       
   655 			case MEM_LEAK_MODULE:
       
   656 			{
       
   657 				if( m_pMemoryLeaks == NULL )
       
   658 					return;
       
   659 				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
       
   660 				m_pMemoryLeaks->appendChild( moduleElement );
       
   661 
       
   662 				// Print module name
       
   663 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   664 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   665 				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
       
   666 
       
   667 				if( wTemp )
       
   668 					delete[] wTemp;
       
   669 				// Print number of memory leaks
       
   670 				wTemp = CharToWChar( sInput.c_str() );
       
   671 				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
       
   672 				if( wTemp )
       
   673 					delete[] wTemp;
       
   674 			}
       
   675 			break;
       
   676 			case HANDLE_LEAKS:
       
   677 			{
       
   678 				if( m_pRunElement == NULL )
       
   679 					return;
       
   680 				if( m_pHandleLeaks )
       
   681 				{
       
   682 					// Update number of leaks
       
   683 					LPWSTR wTemp = CharToWChar( sInput.c_str() );
       
   684 					m_pHandleLeaks->setAttribute( L"count", (const LPWSTR)wTemp );
       
   685 					if( wTemp )
       
   686 						delete[] wTemp;
       
   687 				}
       
   688 				else
       
   689 				{
       
   690 					xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
       
   691 					m_pRunElement->appendChild( handleLeaksElement );
       
   692 					m_pHandleLeaks = handleLeaksElement;
       
   693 
       
   694 					// Print number of leaks
       
   695 					LPWSTR wTemp = CharToWChar( sInput.c_str() );
       
   696 					handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
       
   697 					if( wTemp )
       
   698 						delete[] wTemp;
       
   699 				}
       
   700 			}
       
   701 			break;
       
   702 			case HANDLE_LEAK_MODULE:
       
   703 			{
       
   704 				if( m_pHandleLeaks == NULL )
       
   705 					return;
       
   706 				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
       
   707 				m_pHandleLeaks->appendChild( moduleElement );
       
   708 
       
   709 				// Print module name
       
   710 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   711 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   712 				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
       
   713 				if( wTemp )
       
   714 					delete[] wTemp;
       
   715 
       
   716 				// Print number of memory leaks
       
   717 				wTemp = CharToWChar( sInput.c_str() );
       
   718 				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
       
   719 				if( wTemp )
       
   720 					delete[] wTemp;
       
   721 			}
       
   722 			break;
       
   723 			case TEST_START:
       
   724 			{
       
   725 				m_pCurrentSubTestElem = m_pDomDoc->createElement( L"subtest" );
       
   726 
       
   727 				if( m_pCurrentSubTestElem == NULL || m_pRunElement == NULL )
       
   728 					return;
       
   729 
       
   730 				m_pRunElement->appendChild( m_pCurrentSubTestElem );
       
   731 
       
   732 				// Print sub test name
       
   733 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   734 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   735 				m_pCurrentSubTestElem->setAttribute( L"name", (const LPWSTR)wTemp );
       
   736 				if( wTemp )
       
   737 				{
       
   738 					delete[] wTemp;
       
   739 					wTemp = NULL;
       
   740 				}
       
   741 
       
   742 				// Print sub test time
       
   743 				sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   744 				wTemp = CharToWChar( sTemp.c_str() );
       
   745 				m_pCurrentSubTestElem->setAttribute( L"start_time", (const LPWSTR)wTemp );
       
   746 				if( wTemp )
       
   747 					delete[] wTemp;
       
   748 				break;
       
   749 			}
       
   750 			case TEST_END:
       
   751 			{
       
   752 				if( m_pCurrentSubTestElem == NULL )
       
   753 					return;
       
   754 				// Print end time
       
   755 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   756 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   757 				m_pCurrentSubTestElem->setAttribute( L"end_time", (const LPWSTR)wTemp );
       
   758 				m_pCurrentSubTestElem = NULL;
       
   759 				if( wTemp )
       
   760 					delete[] wTemp;
       
   761 				break;
       
   762 			}
       
   763 			case SUBTEST_MEM_LEAKS:
       
   764 			{
       
   765 				if( m_pCurrentSubTestElem == NULL )
       
   766 					return;
       
   767 				xercesc::DOMElement* memoryLeaksElement = m_pDomDoc->createElement( L"mem_leaks" );
       
   768 				m_pCurrentSubTestElem->appendChild( memoryLeaksElement );
       
   769 				m_pSubtestMemoryLeaks = memoryLeaksElement;
       
   770 
       
   771 				// Print number of leaks
       
   772 				LPWSTR wTemp = CharToWChar( sInput.c_str() );
       
   773 				memoryLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
       
   774 				if( wTemp )
       
   775 					delete[] wTemp;
       
   776 				break;
       
   777 			}
       
   778 			case SUBTEST_MEM_LEAK_MODULE:
       
   779 			{
       
   780 				if( m_pSubtestMemoryLeaks == NULL )
       
   781 					return;
       
   782 				xercesc::DOMElement* moduleElement = m_pDomDoc->createElement( L"module" );
       
   783 				m_pSubtestMemoryLeaks->appendChild( moduleElement );
       
   784 
       
   785 				// Print module name
       
   786 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   787 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   788 				moduleElement->setAttribute( L"name", (const LPWSTR)wTemp );
       
   789 
       
   790 				if( wTemp )
       
   791 					delete[] wTemp;
       
   792 				// Print number of memory leaks
       
   793 				wTemp = CharToWChar( sInput.c_str() );
       
   794 				moduleElement->setAttribute( L"leaks", (const LPWSTR)wTemp );
       
   795 				if( wTemp )
       
   796 					delete[] wTemp;
       
   797 				break;
       
   798 			}
       
   799 			case SUBTEST_HANDLE_LEAKS:
       
   800 			{
       
   801 				if( m_pCurrentSubTestElem == NULL )
       
   802 					return;
       
   803 				xercesc::DOMElement* handleLeaksElement = m_pDomDoc->createElement( L"handle_leaks" );
       
   804 				m_pCurrentSubTestElem->appendChild( handleLeaksElement );
       
   805 
       
   806 				//Print number of handle leaks
       
   807 				string sTemp = GetStringUntilNextGivenChar( sInput, ';' );
       
   808 				LPWSTR wTemp = CharToWChar( sTemp.c_str() );
       
   809 				handleLeaksElement->setAttribute( L"count", (const LPWSTR)wTemp );
       
   810 				if( wTemp )
       
   811 					delete[] wTemp;
       
   812 				break;
       
   813 			}
       
   814 			default:
       
   815 			break;
       
   816 		}
       
   817 	}
       
   818 	catch( ... )
       
   819 	{
       
   820 		printf( "Error when writing data to XML file." );
       
   821 	}
       
   822 }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CATDataSaver::GetStringUntilNextGivenChar
       
   826 // Function returns string from begin of given string until next given char,
       
   827 // characters until given char are removed from sInput string.
       
   828 // -----------------------------------------------------------------------------
       
   829 string CATDataSaver::GetStringUntilNextGivenChar( string& sInput, char cCharacter )
       
   830 {
       
   831 	LOG_LOW_FUNC_ENTRY("CATDataSaver::GetStringUntilNextGivenChar");
       
   832 	string sRet;
       
   833 	size_t iPos = sInput.find( cCharacter );
       
   834 	if( sInput.size() > 1 && iPos != string::npos )
       
   835 	{
       
   836 		sRet = sInput.substr( 0, iPos );
       
   837 		sInput.erase( 0, (iPos + 1) );
       
   838 	}
       
   839 	return sRet;
       
   840 }
       
   841 
       
   842 // -----------------------------------------------------------------------------
       
   843 // CATDataSaver::SetBuild
       
   844 // Function sets build target info.
       
   845 // -----------------------------------------------------------------------------
       
   846 void CATDataSaver::SetBuild( bool bUdebBuild )
       
   847 {
       
   848 	LOG_FUNC_ENTRY("CATDataSaver::SetBuild");
       
   849 	m_bUdebBuild = bUdebBuild;
       
   850 }
       
   851 
       
   852 // -----------------------------------------------------------------------------
       
   853 // CATDataSaver::AddCarbideData
       
   854 // Function adds string to Carbide data.
       
   855 // -----------------------------------------------------------------------------
       
   856 void CATDataSaver::AddCarbideData( const string& sInput )
       
   857 {
       
   858 	LOG_LOW_FUNC_ENTRY("CATDataSaver::AddCarbideData");
       
   859 	m_sCarbideDataLine.append( sInput );
       
   860 	m_sCarbideDataLine.append(";");
       
   861 }
       
   862 
       
   863 // -----------------------------------------------------------------------------
       
   864 // CATDataSaver::IntegerToString
       
   865 // Converts integer to string.
       
   866 // -----------------------------------------------------------------------------
       
   867 string CATDataSaver::IntegerToString( int iValueToConvert )
       
   868 {
       
   869 	LOG_LOW_FUNC_ENTRY("CATDataSaver::IntegerToString");
       
   870 	char cTemp[128];
       
   871 	string sValue( itoa( iValueToConvert, cTemp, 10 ) );
       
   872 	return sValue;
       
   873 }