apicompatanamdw/compatanalysercmd/libraryanalyser/src/la_analysis.cpp
changeset 0 638b9c697799
equal deleted inserted replaced
-1:000000000000 0:638b9c697799
       
     1 /*
       
     2 * Copyright (c) 2007-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:  Functionality of analysis 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "la.hpp"
       
    20 #include "la_parser.hpp"
       
    21 #include "xmlprocessor.hpp"
       
    22 #include "xmldomainmap.hpp"
       
    23 #include "xmlsaxparser.hpp"
       
    24 #include "xmlnode.hpp"
       
    25 #include "xmlsaxhandler.hpp"
       
    26 #include "xmlsaxerrorhandler.hpp"
       
    27 
       
    28 
       
    29 
       
    30 // ----------------------------------------------------------------------------------------------------------
       
    31 
       
    32 typedef XMLSAXHandler<XMLDomainMap<XMLNode> > DOCHANDLER;
       
    33 typedef XMLSAXErrorHandler ERRORHANDLER;
       
    34 typedef XMLSAXParser<DOCHANDLER, ERRORHANDLER> PARSER;
       
    35 typedef XMLProcessor<PARSER> XMLEngine;
       
    36 
       
    37 
       
    38 int XmlTools::initialiseDOM()
       
    39 {
       
    40     try
       
    41     {
       
    42         XMLPlatformUtils::Initialize();
       
    43     } catch (const XMLException& e )
       
    44     {
       
    45         char* message = _X( e.getMessage() );
       
    46         cout << "Error during initialization! :\n" << message << endl ;
       
    47         _XX(message);
       
    48 		    return -1;
       
    49     }
       
    50 
       
    51     DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation( _X("Core") );
       
    52     iParser = ((DOMImplementationLS*)impl)->createDOMBuilder( DOMImplementationLS::MODE_SYNCHRONOUS, 0 );
       
    53     if ( iParser->canSetFeature( XMLUni::fgDOMValidation, true ) )
       
    54         iParser->setFeature( XMLUni::fgDOMValidation, true );
       
    55     if ( iParser->canSetFeature( XMLUni::fgDOMNamespaces, true ) )
       
    56         iParser->setFeature( XMLUni::fgDOMNamespaces, true );
       
    57     if ( iParser->canSetFeature( XMLUni::fgDOMDatatypeNormalization, true ) )
       
    58         iParser->setFeature( XMLUni::fgDOMDatatypeNormalization, true );
       
    59         
       
    60     return 0;
       
    61 }
       
    62 
       
    63 void XmlTools::uninitialiseDOM()
       
    64 {
       
    65     iParser->release();
       
    66     XMLPlatformUtils::Terminate();
       
    67 }
       
    68 
       
    69 XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* XmlTools::readFile( const char* aFilename )
       
    70 {
       
    71 	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc;
       
    72     DOMErrorHandler* myErrorHandler;
       
    73 
       
    74     fstream ifile;
       
    75     bool validate = false;
       
    76     
       
    77     string filedoctype;
       
    78     string doctype("<!DOCTYPE");
       
    79     
       
    80     //check if a document type definition is provided for the xml file
       
    81     ifile.open(aFilename);  
       
    82     ifile >> filedoctype ;
       
    83     ifile.close();
       
    84     
       
    85     if(doctype.compare(filedoctype) == 0)
       
    86         validate = true;
       
    87         
       
    88     //if document type definition present,create and set error handler to parser, to report any parse errors in issues document.
       
    89     if(validate)
       
    90     {
       
    91         myErrorHandler = new DOMPrintErrorHandler();
       
    92         XmlTools::iParser->setErrorHandler(myErrorHandler);	
       
    93     }
       
    94     
       
    95     try
       
    96     {
       
    97         doc = iParser->parseURI( aFilename );
       
    98     }
       
    99     catch ( const XMLException& e )
       
   100     {
       
   101         char* message = _X( e.getMessage() );
       
   102         cout << "Failed to read " << aFilename << ". \"" << message << "\"" << endl ;
       
   103         _XX( message );
       
   104         return NULL;
       
   105     }
       
   106     catch ( const DOMException& e )
       
   107     {
       
   108         char* message = _X( e.getMessage() );
       
   109         cout << "Failed to read " << aFilename << ". \"" << message << "\"" << endl ;
       
   110         _XX( message );
       
   111         return NULL;
       
   112     }
       
   113     catch (...) 
       
   114     {
       
   115         cout << "Failed to read " << aFilename << ". Unexpected error." << endl ;
       
   116     return NULL;
       
   117     }
       
   118     
       
   119     //delete the error handler, if set
       
   120     if(validate)
       
   121         delete myErrorHandler;
       
   122         
       
   123     return doc;
       
   124 }
       
   125 
       
   126 bool DOMPrintErrorHandler::handleError(const DOMError &domError)
       
   127 {
       
   128     // Display whatever error message passed from the parser
       
   129     if (domError.getSeverity() == DOMError::DOM_SEVERITY_WARNING)
       
   130         XERCES_STD_QUALIFIER cerr << "\nWarning Message: ";
       
   131     else if (domError.getSeverity() == DOMError::DOM_SEVERITY_ERROR)
       
   132         XERCES_STD_QUALIFIER cerr << "\nError Message: ";
       
   133     else
       
   134         XERCES_STD_QUALIFIER cerr << "\nFatal Message: ";
       
   135 
       
   136     char *msg = XMLString::transcode(domError.getMessage());
       
   137     DOMLocator *errorLocator = domError.getLocation();
       
   138     XERCES_STD_QUALIFIER cerr<< errorLocator->getLineNumber() << ",";
       
   139     XERCES_STD_QUALIFIER cerr<< errorLocator->getColumnNumber() << ": ";
       
   140     XERCES_STD_QUALIFIER cerr<< msg <<XERCES_STD_QUALIFIER endl;
       
   141     XMLString::release(&msg);
       
   142 
       
   143     // Instructs the parser to continue parsing if possible.
       
   144     return true;
       
   145 }
       
   146 
       
   147 DOMElement* XmlTools::getTagNode( const DOMElement* aParentNode, const char* aTagName )
       
   148 {
       
   149     DOMNodeList* list = aParentNode->getElementsByTagName( _X( aTagName ) );
       
   150     if ( list == NULL || list->getLength() == 0 )
       
   151         return NULL;
       
   152     else
       
   153         return (DOMElement*) list->item( 0 );
       
   154 }
       
   155 
       
   156 int XmlTools::getTagValue( const DOMElement* aParentNode, const char* aTagName, char* aTagValue, int minLen, int maxLen )
       
   157 {
       
   158     DOMNodeList* list = aParentNode->getElementsByTagName( _X( aTagName ) );
       
   159 
       
   160     strcpy( aTagValue, "" );
       
   161     if ( list == NULL || list->getLength() == 0 )
       
   162         return -1;
       
   163     else
       
   164     {
       
   165         DOMNode* textNode = list->item( 0 )->getFirstChild();
       
   166         if ( textNode == NULL )
       
   167             return -1;
       
   168             
       
   169         char* text = _X( textNode->getNodeValue() );
       
   170         if ( text == NULL )
       
   171             return -1;
       
   172             
       
   173 		int len =(int) strlen( text );
       
   174         if ( len < minLen || len > maxLen )
       
   175             return -1;
       
   176             
       
   177         strcpy( aTagValue, text );
       
   178         _XX( text );
       
   179         
       
   180         return 0;
       
   181     }
       
   182 }
       
   183 
       
   184 
       
   185 void ParseAndCompareDLLXmlFiles(const string& abaselineXmlFile,const string& acurrentXmlFile)
       
   186 {
       
   187 	XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* ibaseDoc = NULL;
       
   188 	int currIndx = -1;
       
   189 	int baseIndx = -1;
       
   190 	char dll_name[1024];
       
   191 
       
   192 	if ( XmlTools::initialiseDOM() == -1 )
       
   193         return ;
       
   194 
       
   195 	// read report document
       
   196 	ibaseDoc = XmlTools::readFile( abaselineXmlFile.c_str() );
       
   197 	if ( ibaseDoc == NULL )
       
   198 	{
       
   199 		XmlTools::uninitialiseDOM();
       
   200 		return ;
       
   201 	}
       
   202 
       
   203 	// Parse file
       
   204 	cout << "Gathering dll information... " ;
       
   205 	
       
   206 	//With SAX parser , parse the base xml doc
       
   207 	// Create an instance of our XMLFactory
       
   208 	XMLEngine baseParser(abaselineXmlFile);
       
   209 	// Turn off validation
       
   210 	baseParser.doValidation(false);
       
   211 	baseParser.parse();
       
   212 	
       
   213 
       
   214 	//With SAX parser , parse the current xml doc
       
   215 	// Create an instance of our XMLFactory
       
   216 	XMLEngine currParser(acurrentXmlFile);
       
   217 	// Turn off validation
       
   218 	currParser.doValidation(false);
       
   219 	// Parse our XML file
       
   220 	currParser.parse();
       
   221 
       
   222 	cout << "Done" <<endl;
       
   223 
       
   224 	// Get the tree root
       
   225 	XMLNode baseRoot = baseParser.getRootElement();
       
   226 	XMLNode curRoot = currParser.getRootElement();
       
   227 
       
   228 	int totcurDlls = (int)curRoot.childCount(); 
       
   229 	int totbaseDlls = (int)baseRoot.childCount();
       
   230 
       
   231 	XMLNode dllNorode = curRoot.child("dll",currIndx);	
       
   232 	XMLNode baseNode = baseRoot.child("dll",baseIndx);
       
   233 
       
   234 	//If baseline dll is missing, report it as informative
       
   235 	for(unsigned int outer = 0; outer < _lib_files_baseline.size(); outer++ )
       
   236 	{
       
   237 		dll_issue tempIssue;
       
   238 
       
   239 		string finallibname(_lib_files_baseline.at(outer));
       
   240 		finallibname=getFilename(finallibname);
       
   241 		unsigned int inner;
       
   242 		
       
   243 		for(inner = baseIndx; inner < totbaseDlls; inner++ )
       
   244 		{
       
   245 			XMLNode base_dlllist = baseRoot.children_[inner];
       
   246 
       
   247 			string base_dllname = base_dlllist.child("dllname").value();
       
   248 			base_dllname = getFilename(base_dllname);
       
   249 			if (StringICmpFileNamesWithoutExtension(finallibname,base_dllname) == 0)
       
   250 				break;
       
   251 		}
       
   252 		if (inner == totbaseDlls)
       
   253 		{
       
   254 			intializeDllIssue(tempIssue);
       
   255 			tempIssue.l_dllname = finallibname;
       
   256 			tempIssue.i_list_typeid.push_back(DLL_BASELINE_MISSING);
       
   257 			_dll_issuelist.push_back(tempIssue);			
       
   258 		}
       
   259 	}
       
   260 	
       
   261     // get dll breaks by comparing baseline and current dll data file
       
   262 	if (baseIndx >=0 && currIndx>=0)
       
   263 	{
       
   264 		for (unsigned long i = baseIndx; i < totbaseDlls; ++i )
       
   265 		{
       
   266 			dll_issue issue;
       
   267 			XMLNode base_dlllist = baseRoot.children_[i];
       
   268 			if ( base_dlllist.childCount() == 0 )
       
   269 				continue;
       
   270 			string base_dllname = base_dlllist.child("dllname").value();
       
   271 			base_dllname = getFilename(base_dllname);
       
   272 			
       
   273 			int l;
       
   274 			//char baseVal[5][255];
       
   275 			char attribs[5][12] = { "uid1", "uid2", "uid3", "sid" ,"capability"};			
       
   276 			
       
   277 			if (base_dllname.size() > 0 )
       
   278 			{
       
   279 				intializeDllIssue(issue);				
       
   280 				issue.l_dllname = base_dllname;
       
   281 				string baseShortName = getFilename(base_dllname);
       
   282 				int curIter;
       
   283 				
       
   284 				for( curIter = currIndx ; curIter < totcurDlls ; curIter++ )
       
   285 				{
       
   286 					XMLNode curr_dlllist = curRoot.children_[curIter];
       
   287 					
       
   288 					string cur_dllname = curr_dlllist.child("dllname").value();
       
   289 					cur_dllname = getFilename(cur_dllname);
       
   290 					vector<unsigned int> typeId_list;
       
   291 									
       
   292 					if(stricmp (baseShortName.c_str(),cur_dllname.c_str()) == 0)
       
   293 					{						
       
   294 
       
   295 						for ( l = 0; l < 5; ++ l )
       
   296 						{
       
   297 							string curVal = curr_dlllist.child(attribs[l]).value();
       
   298 							string baseVal = base_dlllist.child(attribs[l]).value();
       
   299 							unsigned int typeId = 0;
       
   300 
       
   301 							if(l == 4) // capability check
       
   302 							{
       
   303 								unsigned long baseCap =parseHex(baseVal.c_str());
       
   304 								unsigned long curCap = parseHex(curVal.c_str());
       
   305 								unsigned long resultCap = baseCap & curCap;
       
   306 								if( baseCap != resultCap)
       
   307 									typeId_list.push_back(DLL_CAPABILITY_CHANGED);
       
   308 							}							
       
   309 							else if( curVal.compare(baseVal)!= 0)
       
   310 							{								
       
   311 								fillDllIssue(attribs[l], typeId);
       
   312 								typeId_list.push_back(typeId);
       
   313 							}
       
   314 						}
       
   315 						
       
   316 						if(typeId_list.size()> 0 )
       
   317 						{
       
   318 							issue.i_list_typeid = typeId_list;
       
   319 							_dll_issuelist.push_back(issue);
       
   320 						}
       
   321 						break;
       
   322 					}
       
   323 				}
       
   324 
       
   325 				if (curIter == totcurDlls ) // missing dll in current xml file
       
   326 				{
       
   327 					issue.i_list_typeid.push_back( DLL_CURRENT_MISSING);
       
   328 					_dll_issuelist.push_back(issue);	
       
   329 				}
       
   330 			}
       
   331 
       
   332 		}
       
   333 	}//end of dll list
       
   334 	
       
   335 	XmlTools::uninitialiseDOM();
       
   336 }
       
   337 
       
   338 void WriteReportHeader()
       
   339 {
       
   340     _reportf.open(_cl_reportfile.c_str(), ios::trunc);
       
   341 
       
   342     if (!_reportf.is_open())
       
   343         {
       
   344 			cerr << "ERROR: Cannot open " << _cl_reportfile << " for writing!" << endl;
       
   345 			cerr << "Please check that the directory exists and there are no write permission problems" << endl;
       
   346 			exit(EXIT_CANNOT_WRITE_TO_REPORT_FILE);
       
   347         }
       
   348 
       
   349     WriteXMLLineOpeningTag(_reportf, 0, "?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?");
       
   350     WriteXMLLineOpeningTag(_reportf, 0, "?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?");
       
   351     WriteXMLLineOpeningTag(_reportf, 0, "bbcresults");
       
   352     WriteXMLLineOpeningTag(_reportf, 1, "header");
       
   353 
       
   354     WriteXMLLineOpenClosed(_reportf, 2, "baselineversion", _cl_baselineversion);
       
   355     WriteXMLLineOpenClosed(_reportf, 2, "currentversion", _cl_currentversion);
       
   356 
       
   357     WriteXMLLineOpeningTag(_reportf, 2, "timestamp");
       
   358     WriteXMLLineOpenClosed(_reportf, 3, "day", Int2Str(_timenow->tm_mday));
       
   359     WriteXMLLineOpenClosed(_reportf, 3, "month", Int2Str(_timenow->tm_mon + 1));
       
   360     WriteXMLLineOpenClosed(_reportf, 3, "year", Int2Str(1900 + _timenow->tm_year));
       
   361     WriteXMLLineOpenClosed(_reportf, 3, "hour", Int2Str(_timenow->tm_hour));
       
   362     WriteXMLLineOpenClosed(_reportf, 3, "minute", Int2Str(_timenow->tm_min));
       
   363     WriteXMLLineOpenClosed(_reportf, 3, "second", Int2Str(_timenow->tm_sec));
       
   364     WriteXMLLineClosingTag(_reportf, 2, "timestamp");
       
   365 
       
   366     WriteXMLLineOpenClosed(_reportf, 2, "laversion", LA_VERSION);
       
   367     WriteXMLLineOpenClosed(_reportf, 2, "formatversion", LA_REPORT_FORMAT_VERSION);
       
   368 
       
   369     WriteXMLLineOpeningTag(_reportf, 2, "cmdlineparms");
       
   370 
       
   371     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   372     WriteXMLLineOpenClosed(_reportf, 4, "pname", "toolchain");
       
   373     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _toolchain_name);
       
   374     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   375 
       
   376     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   377     WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselinelibdir");
       
   378     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselinelibdir);
       
   379     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   380 
       
   381     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   382     WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentlibdir");
       
   383     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentlibdir);
       
   384     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   385     
       
   386     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   387     WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselinedlldir");
       
   388     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselinedlldir);
       
   389     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   390 
       
   391     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   392     WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentdlldir");
       
   393     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentdlldir);
       
   394     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   395     
       
   396     if(_cl_baselinedlldir.empty() || _cl_currentdlldir.empty())
       
   397     {
       
   398       WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   399       WriteXMLLineOpenClosed(_reportf, 4, "pname", "warning");
       
   400       WriteXMLLineOpenClosed(_reportf, 4, "pvalue","Required parameters for checking dll properties not specified. Compatibility Breaks in dll are not checked." );
       
   401       WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   402     }
       
   403 
       
   404     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   405     WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselineversion");
       
   406     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselineversion);
       
   407     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   408 
       
   409     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   410     WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentversion");
       
   411     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentversion);
       
   412     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   413 
       
   414     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   415     WriteXMLLineOpenClosed(_reportf, 4, "pname", "reportfile");
       
   416     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_reportfile);
       
   417     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   418 
       
   419     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   420     WriteXMLLineOpenClosed(_reportf, 4, "pname", "tools");
       
   421     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_toolsdir);
       
   422     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   423 
       
   424     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   425     WriteXMLLineOpenClosed(_reportf, 4, "pname", "temp");
       
   426     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_tempdir);
       
   427     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   428     
       
   429     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   430     WriteXMLLineOpenClosed(_reportf, 4, "pname", "cfilt");
       
   431     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_cfiltloc);
       
   432     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   433 
       
   434     WriteXMLLineOpeningTag(_reportf, 3, "parm");
       
   435     WriteXMLLineOpenClosed(_reportf, 4, "pname", "set");
       
   436     WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_set);
       
   437     WriteXMLLineClosingTag(_reportf, 3, "parm");
       
   438 
       
   439     WriteXMLLineClosingTag(_reportf, 2, "cmdlineparms");
       
   440 
       
   441     WriteXMLLineOpenClosed(_reportf, 2, "knownissuesversion", "");
       
   442     
       
   443     WriteXMLLineClosingTag(_reportf, 1, "header");
       
   444     WriteXMLLineOpeningTag(_reportf, 1, "issuelist");    
       
   445 }
       
   446 
       
   447 // ----------------------------------------------------------------------------------------------------------
       
   448 
       
   449 void GenerateAndWriteIssueList()
       
   450 {
       
   451 	int total_files = _lib_files_baseline.size();
       
   452 	int current_files = 0;
       
   453 	cout <<"Total baseline files "<< _lib_files_baseline.size() << endl;
       
   454 	cout <<"Total current files "<< _lib_files_current.size() << endl;
       
   455 	
       
   456 	vector<string>::const_iterator itr;
       
   457 	for (unsigned int i=0; i<_lib_files_current.size(); i++)
       
   458 	{
       
   459 		bool exists = false;
       
   460 		// check if the same lib exists in baselinedir
       
   461 		for(itr = _lib_dirs_baseline.begin(); itr != _lib_dirs_baseline.end(); itr++)
       
   462 		{
       
   463 			if (FileExists(*itr + getFilename(_lib_files_current.at(i))))
       
   464 			{
       
   465 				exists = true;
       
   466 				break;
       
   467 			}
       
   468 		}
       
   469 		if(!exists)
       
   470 		{
       
   471 			total_files++;
       
   472 		}
       
   473 	}
       
   474 	cout <<"Total files to be processed "<< total_files << endl;
       
   475 	//vector<dll_issue> dll_issuelist;
       
   476     
       
   477 	dll_issue reportdll;
       
   478 	string dllname;
       
   479 
       
   480 	if(_baselinedllfile.size() > 0 && _currentdllfile.size() > 0)
       
   481 	{
       
   482 		ParseAndCompareDLLXmlFiles(_baselinedllfile,_currentdllfile );
       
   483 	}
       
   484 	
       
   485 	unsigned int dllIssueCount = _dll_issuelist.size();
       
   486 
       
   487     // first go through all libs in the baseline set
       
   488 	for (unsigned int i=0; i<_lib_files_baseline.size(); i++)
       
   489 	{
       
   490 		unsigned int k;
       
   491 		vector<string>::iterator itr = _lib_files_current.end();
       
   492 		bool exists = false;
       
   493 
       
   494 		//check if the same dll is present in exe_issue, if yes then add it to final report
       
   495 		intializeDllIssue(reportdll);
       
   496 		for(unsigned int indx = 0; indx < dllIssueCount; indx++)
       
   497 		{
       
   498 			dll_issue lIssue;
       
   499 			lIssue = _dll_issuelist.at(indx);		
       
   500 			if(StringICmpFileNamesWithoutExtension(getFilename(lIssue.l_dllname),getFilename(_lib_files_baseline.at(i))) == 0)
       
   501 			{
       
   502 				reportdll = lIssue;
       
   503 				break;
       
   504 			}
       
   505 		}
       
   506 
       
   507 
       
   508         // check if the same lib exists in currentdir
       
   509         for(k = 0; k < _lib_dirs_current.size(); k++)
       
   510 		    {
       
   511 			      string file = _lib_dirs_current.at(k) + getFilename(_lib_files_baseline.at(i));
       
   512 			      if (FileExists( file ))
       
   513 			      {
       
   514 			          for(itr=_lib_files_current.begin() ; itr != _lib_files_current.end() ; ++itr)
       
   515 			          {
       
   516 			              if(StringICmp(file,*itr)== 0)
       
   517 			              {
       
   518 			                  exists = true;
       
   519 			                  break;
       
   520 			              }
       
   521 			          }
       
   522 			          if(exists)
       
   523 			              break;
       
   524 			      }
       
   525 			  }
       
   526 
       
   527         // check if the same lib exists in currentdir
       
   528         if (!exists)
       
   529         {
       
   530         	  cout.precision(0);
       
   531             cout << "\nAnalysing files (" << current_files+1 << "/" << total_files << "): " << _lib_files_baseline.at(i) << endl;  
       
   532 
       
   533 			WriteXMLIssueOnlyInBaselineDir(_reportf, _lib_files_baseline.at(i),reportdll);
       
   534         }
       
   535         else
       
   536         {
       
   537             cout.precision(0);
       
   538             cout << "\nAnalysing files (" << current_files+1 << "/" << total_files << "): " << _lib_files_baseline.at(i) << " => " << *itr << endl;  
       
   539             // both files are available, now get the symbol table and do the comparision process
       
   540             vector<string> symbol_table_baseline;
       
   541             vector<string> symbol_table_current;
       
   542 
       
   543             // get the symbol tables of the libraries
       
   544             if (_cl_use_gcc)
       
   545             {
       
   546                 GetSymbolTableWithNM(_gcc_nm_location, _lib_files_baseline.at(i), symbol_table_baseline);
       
   547                 GetSymbolTableWithNM(_gcc_nm_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current);
       
   548             }
       
   549             else if (_cl_use_gcce)
       
   550             {
       
   551                 if (_cl_use_libs)
       
   552                 {
       
   553                     GetSymbolTableWithNM(_gcce_nm_location, _lib_files_baseline.at(i), symbol_table_baseline);
       
   554                     GetSymbolTableWithNM(_gcce_nm_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current);
       
   555                 }
       
   556                 else
       
   557                 {
       
   558                     GetSymbolTableWithReadelf(_gcce_readelf_location, _gcce_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline);
       
   559                     GetSymbolTableWithReadelf(_gcce_readelf_location, _gcce_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current);
       
   560                 }
       
   561             }
       
   562             else if (_cl_use_rvct)
       
   563             {
       
   564                 if (_cl_use_libs)
       
   565                 {
       
   566                     GetSymbolTableWithArmar(_rvct_armar_location, _rvct_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline);
       
   567                     GetSymbolTableWithArmar(_rvct_armar_location, _rvct_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current);
       
   568                 }
       
   569                 else
       
   570                 {
       
   571                     GetSymbolTableWithFromelf(_rvct_fromelf_location, _rvct_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline);
       
   572                     GetSymbolTableWithFromelf(_rvct_fromelf_location, _rvct_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current);
       
   573                 }
       
   574             }
       
   575 
       
   576             // create a vector to store all issues of this library
       
   577             vector<issue> issue_list;
       
   578 			//Local variable to store severity of the issue
       
   579 			TypeOfSeverity severity = NO_BREAK;
       
   580             // create and init vectors to store ordinal state
       
   581             vector<bool> matched_baseline;
       
   582             vector<bool> checked_baseline;
       
   583             vector<bool> matched_current;
       
   584             vector<bool> checked_current;
       
   585 			vector<TypeOfSeverity> map_severity;
       
   586             
       
   587             for (unsigned int j=0; j<symbol_table_baseline.size(); j++)
       
   588                 matched_baseline.push_back(false);
       
   589 
       
   590             for (unsigned int j=0; j<symbol_table_baseline.size(); j++)
       
   591                 checked_baseline.push_back(false);
       
   592 
       
   593             for (unsigned int j=0; j<symbol_table_current.size(); j++)
       
   594                 matched_current.push_back(false);
       
   595 
       
   596             for (unsigned int j=0; j<symbol_table_current.size(); j++)
       
   597                 checked_current.push_back(false);
       
   598 			//Initially set to NO_BREAK as the type of severity
       
   599             for (unsigned int j=0; j<symbol_table_baseline.size(); j++)
       
   600                 map_severity.push_back(NO_BREAK);
       
   601 
       
   602 
       
   603             // first loop through all ordinals in baseline to find matches
       
   604             for (unsigned int j=0; j<symbol_table_baseline.size(); j++)
       
   605             {
       
   606                 bool need_to_check_moving = false;
       
   607 
       
   608                 if (j < symbol_table_current.size())
       
   609                 {
       
   610                     // check if it's an exact match or otherwise binary compatible
       
   611                     if ( symbol_table_baseline.at(j) == symbol_table_current.at(j) ||
       
   612                         (severity = AreFunctionsCompatible(symbol_table_baseline.at(j), symbol_table_current.at(j)))
       
   613 						 == NO_BREAK )
       
   614                     {
       
   615                         // match!
       
   616                         matched_baseline.at(j) = true;
       
   617                         matched_current.at(j) = true;
       
   618 
       
   619                         checked_baseline.at(j) = true;
       
   620                         checked_current.at(j) = true;
       
   621                     }                    
       
   622                     else
       
   623 					{
       
   624 						// possibly moved
       
   625 						need_to_check_moving = true;
       
   626 						//store the severity
       
   627 						map_severity.at(j) = severity;
       
   628 					}
       
   629                 }
       
   630                 else
       
   631                 {
       
   632                     // it's out of range, so it can be a match, but check if it has moved
       
   633                     need_to_check_moving = true;
       
   634                 }   
       
   635                 
       
   636                 // now do the actual checking if it has moved
       
   637                 if (need_to_check_moving)
       
   638                 {
       
   639                     for (unsigned int l=0; l<symbol_table_current.size(); l++)
       
   640                     {
       
   641                         if (symbol_table_baseline.at(j) == symbol_table_current.at(l))
       
   642                         {
       
   643 							// match found, mark as moved
       
   644 							map_severity.at(j) = CONFIRMED_BC_BREAK;
       
   645                             AppendToIssueListCaseMoved(issue_list, symbol_table_baseline.at(j), j+1, l+1,map_severity.at(j));
       
   646                             
       
   647                             matched_baseline.at(j) = true;
       
   648                             matched_current.at(l) = true;
       
   649 
       
   650                             checked_baseline.at(j) = true;
       
   651                             checked_current.at(l) = true;
       
   652 
       
   653                         } // if
       
   654                     } // for           
       
   655                 } // if (need_to_check_moving)
       
   656             } // for (int j=0; j<symbol_table_baseline.size(); j++)
       
   657            
       
   658 
       
   659             // check for removed ordinals when no corresponding ordinals in current
       
   660             if (checked_baseline.size() > checked_current.size())
       
   661             {
       
   662                 for (unsigned int j=checked_current.size(); j<checked_baseline.size(); j++)
       
   663                 {
       
   664                     if (checked_baseline.at(j) == false)
       
   665                     {
       
   666                         // ignore any absent exports
       
   667                         string::size_type loc = symbol_table_baseline.at(j).find("_._.absent_export", 0);
       
   668                         
       
   669                         // mark as removed if not marked as absent
       
   670                         if( loc == string::npos )
       
   671 						{
       
   672 							// As removed results in both BC and SC break.
       
   673 							map_severity.at(j) = CONFIRMED_BC_AND_SC_BREAK;
       
   674                             AppendToIssueListCaseRemoved(issue_list, symbol_table_baseline.at(j), j+1,map_severity.at(j));
       
   675 						}
       
   676 
       
   677                         checked_baseline.at(j) = true;
       
   678                     }         
       
   679                 }          
       
   680             }
       
   681 
       
   682             // check for added ordinals when no corresponding ordinals in current
       
   683             if (checked_baseline.size() < checked_current.size())
       
   684             {
       
   685                 for (unsigned int j=checked_baseline.size(); j<checked_current.size(); j++)
       
   686                 {
       
   687                     if (checked_current.at(j) == false)
       
   688                     {
       
   689                     // ignore any absent exports
       
   690                     string::size_type loc = symbol_table_current.at(j).find("_._.absent_export", 0);
       
   691                     
       
   692                     // mark as added if not marked as absent
       
   693                     if( loc == string::npos )
       
   694                         AppendToIssueListCaseAdded(issue_list, symbol_table_current.at(j), j+1,BC_INFORMATIVE);
       
   695 
       
   696                     checked_current.at(j) = true;
       
   697                     }         
       
   698                 }          
       
   699             }
       
   700 
       
   701             // check for removed cases when current has a match at the same ordinal
       
   702             for (unsigned int j=0; j<checked_baseline.size(); j++)
       
   703             {
       
   704                 if (checked_baseline.at(j) == false && matched_current.at(j) == true)
       
   705                 {
       
   706                     // ignore any absent exports
       
   707                     string::size_type loc = symbol_table_baseline.at(j).find("_._.absent_export", 0);
       
   708                     
       
   709                     // mark as removed if not marked as absent
       
   710                     if( loc == string::npos )
       
   711 					{
       
   712 						// As removed results in both BC and SC break.
       
   713 						map_severity.at(j) = CONFIRMED_BC_AND_SC_BREAK;
       
   714 						AppendToIssueListCaseRemoved(issue_list, symbol_table_baseline.at(j), j+1,map_severity.at(j));
       
   715 					}
       
   716 
       
   717                     checked_baseline.at(j) = true;
       
   718                 }         
       
   719             }             
       
   720 
       
   721             // check for inserted cases
       
   722             for (unsigned int j=0; j<checked_current.size(); j++)
       
   723             {
       
   724                 if (checked_current.at(j) == false && matched_baseline.at(j) == true)
       
   725                 {
       
   726                     // ignore any absent exports
       
   727                     string::size_type loc = symbol_table_current.at(j).find("_._.absent_export", 0);
       
   728                     
       
   729                     // mark as inserted if not marked as absent
       
   730                     if( loc == string::npos )
       
   731                         AppendToIssueListCaseInserted(issue_list, symbol_table_current.at(j), j+1,CONFIRMED_BC_BREAK);
       
   732 
       
   733                     checked_current.at(j) = true;
       
   734                 }         
       
   735             }  
       
   736 
       
   737             // check for modified cases
       
   738             for (unsigned int j=0; j<checked_baseline.size(); j++)
       
   739             {
       
   740                 if (checked_baseline.at(j) == false && checked_current.at(j) == false && matched_current.at(j) == false)
       
   741                 {
       
   742                     // ignore any absent exports
       
   743                     string::size_type loc = symbol_table_baseline.at(j).find("_._.absent_export", 0);
       
   744                     string::size_type loc2 = symbol_table_current.at(j).find("_._.absent_export", 0);
       
   745 
       
   746                     // mark as modfied if not marked as absent
       
   747                     if( loc == string::npos && loc2 == string::npos)
       
   748                         AppendToIssueListCaseModified(issue_list, symbol_table_baseline.at(j), symbol_table_current.at(j), j+1,map_severity.at(j));
       
   749                     // mark as added if absent export has been modified to something else
       
   750                     else if (loc != string::npos && loc2 == string::npos)
       
   751                         AppendToIssueListCaseAdded(issue_list, symbol_table_current.at(j), j+1,BC_INFORMATIVE);
       
   752                     // mark as removed if export has been modified as absent
       
   753                     else if (loc == string::npos && loc2 != string::npos)
       
   754                         AppendToIssueListCaseRemoved(issue_list, symbol_table_baseline.at(j), j+1,CONFIRMED_BC_AND_SC_BREAK);
       
   755                         
       
   756                     checked_baseline.at(j) = true;
       
   757                     checked_current.at(j) = true;
       
   758                 }         
       
   759             }   
       
   760 
       
   761             // do some error checking :)
       
   762             for (unsigned int j=0; j<checked_baseline.size(); j++)
       
   763             {
       
   764                 if (checked_baseline.at(j) == false)
       
   765                 {
       
   766                     cout << "OC ALGORITHM ERROR: Baseline func " << symbol_table_baseline.at(j) << " not checked!" << endl;
       
   767                 }         
       
   768             } 
       
   769             for (unsigned int j=0; j<checked_current.size(); j++)
       
   770             {
       
   771                 if (checked_current.at(j) == false)
       
   772                 {
       
   773                     cout << "OC ALGORITHM ERROR: Current rel func " << symbol_table_current.at(j) << " not checked!" << endl;
       
   774                 }         
       
   775             }
       
   776 
       
   777             // sort the issue list
       
   778             sort(issue_list.begin(), issue_list.end(), IssueCompare);
       
   779 
       
   780             // finally write the issue_list to the xml file
       
   781 			WriteIssueListToXML(_reportf, _lib_files_baseline.at(i), *itr /*_lib_files_current.at(i)*/,  issue_list, reportdll);
       
   782             
       
   783         } // else of (!FileExists(_cl_currentlibdir + _lib_files_baseline.at(i)))
       
   784         //erase analysed file from vector, so that files with duplicate names will be properly analysed.
       
   785         if( _lib_files_current.end() != itr )
       
   786             _lib_files_current.erase(itr);
       
   787 
       
   788         current_files++;
       
   789 	} // for (unsigned int i=0; i<_lib_files_baseline.size(); i++)
       
   790 
       
   791 
       
   792     // finally go through all libs in the currentdir set
       
   793 	for (unsigned int i=0; i<_lib_files_current.size(); i++)
       
   794 	{
       
   795 		bool exists = false;
       
   796 		vector<string>::const_iterator itr = _lib_dirs_baseline.begin();
       
   797         // check if the same lib exists in baselinedir
       
   798 		for(;itr != _lib_dirs_baseline.end(); itr++)
       
   799 		{
       
   800 			if (FileExists(*itr + getFilename( _lib_files_current.at(i)) ))
       
   801 			{
       
   802 				exists = true;
       
   803 				break;
       
   804 			}
       
   805 		}
       
   806 		if(!exists)
       
   807 		{
       
   808              current_files++;
       
   809              cout.precision(0);
       
   810              cout << "\nAnalysing files (" << current_files << "/" << total_files << "): " << _lib_files_current.at(i) << endl;  
       
   811 
       
   812              // only in currentdir
       
   813              WriteXMLIssueOnlyInCurrentDir(_reportf, _lib_files_current.at(i));
       
   814         }
       
   815     }
       
   816 	cout << "\n---------------------------------------------";
       
   817 	cout << "\nFinished";
       
   818 	cout << "\nTotal Files analysed : " << total_files;
       
   819 	cout << "\n---------------------------------------------";
       
   820 }
       
   821 
       
   822 // ----------------------------------------------------------------------------------------------------------
       
   823     
       
   824 void WriteReportFooter()
       
   825 {
       
   826     // generate the footer of XML file
       
   827     WriteXMLLineClosingTag(_reportf, 1, "issuelist");
       
   828     WriteXMLLineClosingTag(_reportf, 0, "bbcresults");
       
   829 
       
   830     // close writing to the report file
       
   831     _reportf.close();    
       
   832 }
       
   833 
       
   834 // ----------------------------------------------------------------------------------------------------------
       
   835 
       
   836 void AppendToIssueListCaseMoved(vector<issue>& issueList, const string& funcname, int funcpos, int newfuncpos,TypeOfSeverity severity)
       
   837 {
       
   838 	issue i;
       
   839 	string bc_severity = "";
       
   840 	string sc_severity = "";
       
   841 	getSeverityString(severity,bc_severity,sc_severity);
       
   842 
       
   843 	i.i_typeid = ISSUE_MOVED;
       
   844 	i.i_funcname = funcname;
       
   845 	i.i_newfuncname = "";
       
   846 	i.i_funcpos = funcpos;
       
   847 	i.i_newfuncpos = newfuncpos;
       
   848 	i.i_BC_severity = bc_severity;
       
   849 	i.i_SC_severity = sc_severity;
       
   850 	
       
   851     issueList.push_back(i); 
       
   852 }
       
   853 
       
   854 // ----------------------------------------------------------------------------------------------------------
       
   855 
       
   856 void AppendToIssueListCaseRemoved(vector<issue>& issue_list, const string& funcname, int funcpos,TypeOfSeverity severity)
       
   857 {
       
   858 	issue i;
       
   859 	string bc_severity = "";
       
   860 	string sc_severity = "";
       
   861 	getSeverityString(severity,bc_severity,sc_severity);
       
   862 
       
   863 	i.i_typeid = ISSUE_REMOVED;
       
   864 	i.i_funcname = funcname;
       
   865 	i.i_newfuncname = "";
       
   866 	i.i_funcpos = funcpos;
       
   867 	i.i_newfuncpos = 0;
       
   868 	i.i_BC_severity = bc_severity;
       
   869 	i.i_SC_severity = sc_severity;
       
   870 	
       
   871 	issue_list.push_back(i); 
       
   872 }
       
   873 
       
   874 // ----------------------------------------------------------------------------------------------------------
       
   875 
       
   876 void AppendToIssueListCaseInserted(vector<issue>& issue_list, const string& newfuncname, int newfuncpos,TypeOfSeverity severity)
       
   877 {
       
   878 	issue i;
       
   879 	string bc_severity = "";
       
   880 	string sc_severity = "";
       
   881 	getSeverityString(severity,bc_severity,sc_severity);
       
   882 
       
   883 	i.i_typeid = ISSUE_INSERTED;
       
   884 	i.i_funcname = "";
       
   885 	i.i_newfuncname = newfuncname;
       
   886 	i.i_funcpos = 0;
       
   887 	i.i_newfuncpos = newfuncpos;
       
   888 	i.i_BC_severity = bc_severity;
       
   889 	i.i_SC_severity = sc_severity;
       
   890 	
       
   891 	issue_list.push_back(i); 
       
   892 }
       
   893 
       
   894 // ----------------------------------------------------------------------------------------------------------
       
   895 
       
   896 void AppendToIssueListCaseModified(vector<issue>& issue_list, const string& funcname, const string& newfuncname, int funcpos,TypeOfSeverity severity)
       
   897 {
       
   898 	issue i;
       
   899 	string bc_severity = "";
       
   900 	string sc_severity = "";
       
   901 	getSeverityString(severity,bc_severity,sc_severity);
       
   902 
       
   903 	i.i_typeid = ISSUE_MODIFIED;
       
   904 	i.i_funcname = funcname;
       
   905 	i.i_newfuncname = newfuncname;
       
   906 	i.i_funcpos = funcpos;
       
   907 	i.i_newfuncpos = 0;
       
   908 	i.i_BC_severity = bc_severity;
       
   909 	i.i_SC_severity = sc_severity;
       
   910 	
       
   911 	issue_list.push_back(i); 
       
   912 }
       
   913 
       
   914 // ----------------------------------------------------------------------------------------------------------
       
   915 
       
   916 void AppendToIssueListCaseAdded(vector<issue>& issue_list, const string& newfuncname, int newfuncpos,TypeOfSeverity severity)
       
   917 {
       
   918 	issue i;
       
   919 	string bc_severity = "";
       
   920 	string sc_severity = "";
       
   921 	getSeverityString(severity,bc_severity,sc_severity);
       
   922 
       
   923 	i.i_typeid = ISSUE_ADDED;
       
   924 	i.i_funcname = "";
       
   925 	i.i_newfuncname = newfuncname;
       
   926 	i.i_funcpos = 0;
       
   927 	i.i_newfuncpos = newfuncpos;
       
   928 	i.i_BC_severity = bc_severity;
       
   929 	i.i_SC_severity = sc_severity;
       
   930 
       
   931 	issue_list.push_back(i); 
       
   932 }
       
   933 
       
   934 // ----------------------------------------------------------------------------------------------------------
       
   935 
       
   936 bool IssueCompare(const issue& left, const issue& right)
       
   937 {
       
   938     if (left.i_funcpos > 0 && right.i_funcpos > 0)
       
   939     {
       
   940         if (left.i_funcpos == right.i_funcpos && left.i_newfuncpos > 0 && right.i_newfuncpos > 0)
       
   941             return left.i_newfuncpos < right.i_newfuncpos;
       
   942         else
       
   943             return left.i_funcpos < right.i_funcpos; 
       
   944     }
       
   945     
       
   946     else if (left.i_funcpos == 0 && right.i_funcpos > 0)
       
   947     {
       
   948         if (left.i_newfuncpos == right.i_funcpos)
       
   949             return left.i_funcpos < right.i_newfuncpos;
       
   950         else
       
   951             return left.i_newfuncpos < right.i_funcpos;
       
   952     }
       
   953     
       
   954     else if (left.i_funcpos > 0 && right.i_funcpos == 0)
       
   955     {
       
   956         if (left.i_funcpos == right.i_newfuncpos)
       
   957             return left.i_newfuncpos < right.i_funcpos;
       
   958         else
       
   959             return left.i_funcpos < right.i_newfuncpos;
       
   960     }
       
   961        
       
   962     else // if (left.i_funcpos == 0 && right.i_funcpos == 0)
       
   963     {
       
   964         return left.i_newfuncpos < right.i_newfuncpos;
       
   965     }
       
   966 }
       
   967 
       
   968 // ----------------------------------------------------------------------------------------------------------
       
   969 
       
   970 void WriteXMLLineOpenClosed(ofstream& f, unsigned int tabstops, const string& element, const string& data)
       
   971 {
       
   972     string tabs(tabstops, REPORT_TAB_CHAR);
       
   973     string xmldata(data);
       
   974     
       
   975     // replace & -> &auml;
       
   976     string::size_type i=0;
       
   977     while ((i=xmldata.find("&", i)) != string::npos)
       
   978     {
       
   979         xmldata.replace(i, 1, "&amp;");
       
   980         i++;
       
   981     }
       
   982 
       
   983     // replace < -> &lt;
       
   984     i=0;
       
   985     while ((i=xmldata.find("<", i)) != string::npos)
       
   986         xmldata.replace(i, 1, "&lt;");    
       
   987 
       
   988     // replace > -> &gt;
       
   989     i=0;
       
   990     while ((i=xmldata.find(">", i)) != string::npos)
       
   991         xmldata.replace(i, 1, "&gt;");    
       
   992 
       
   993 
       
   994     f << tabs << "<" << element << ">" << xmldata << "</" << element << ">" << endl;
       
   995 }
       
   996 
       
   997 // ----------------------------------------------------------------------------------------------------------
       
   998 
       
   999 void WriteXMLLineOpeningTag(ofstream& f, unsigned int tabstops, const string& element)
       
  1000 {
       
  1001     string tabs(tabstops, REPORT_TAB_CHAR);
       
  1002 
       
  1003     f << tabs << "<" << element << ">" << endl;
       
  1004 }
       
  1005 
       
  1006 // ----------------------------------------------------------------------------------------------------------
       
  1007 
       
  1008 void WriteXMLLineClosingTag(ofstream& f, unsigned int tabstops, const string& element)
       
  1009 {
       
  1010     string tabs(tabstops, REPORT_TAB_CHAR);
       
  1011 
       
  1012     f << tabs << "</" << element << ">" << endl;
       
  1013 }
       
  1014 
       
  1015 // ----------------------------------------------------------------------------------------------------------
       
  1016 
       
  1017 void writeXMLIssueLibraryHeader(ofstream& f, const string& libname, const string& curlibname)
       
  1018 {
       
  1019     
       
  1020     WriteXMLLineOpeningTag(f, 2, "library");
       
  1021     WriteXMLLineOpenClosed(f, 3, "name", libname);
       
  1022     WriteXMLLineOpenClosed(f, 3, "comparefilename", curlibname);
       
  1023     
       
  1024     string finallibname(curlibname);
       
  1025     if (finallibname.empty())
       
  1026        finallibname=libname;
       
  1027     finallibname=getFilename(finallibname);
       
  1028     // remove any extensions from libname
       
  1029     string::size_type dot_loc = finallibname.find_last_of(".");
       
  1030     if (dot_loc != string::npos)
       
  1031         finallibname = finallibname.substr(0, dot_loc);    
       
  1032     WriteXMLLineOpenClosed(f, 3, "shortname", finallibname);
       
  1033     WriteXMLLineOpenClosed(f, 3, "baseplatform", getPlatform(libname));
       
  1034     WriteXMLLineOpenClosed(f, 3, "currentplatform", getPlatform(curlibname));
       
  1035 }
       
  1036 
       
  1037 // ----------------------------------------------------------------------------------------------------------
       
  1038 
       
  1039 void writeXMLIssueLibraryFooter(ofstream& f)
       
  1040 {
       
  1041     WriteXMLLineClosingTag(f, 2, "library");
       
  1042 }
       
  1043 
       
  1044 // ----------------------------------------------------------------------------------------------------------
       
  1045 
       
  1046 void WriteXMLIssueOnlyInBaselineDir(ofstream& f, const string& libname, dll_issue& dllIssue)
       
  1047 {
       
  1048 	writeXMLIssueLibraryHeader(f, libname, "");
       
  1049 	WriteXMLLineOpeningTag(f, 3, "issue");
       
  1050 	WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(ISSUE_ONLY_IN_BASELINEDIR));
       
  1051 	WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break");
       
  1052 	WriteXMLLineOpenClosed(f, 4, "sc_severity", "SC Break");
       
  1053 	WriteXMLLineClosingTag(f, 3, "issue");
       
  1054 	for(unsigned int i =0; i< dllIssue.i_list_typeid.size(); i++ )
       
  1055 	{
       
  1056 		string typeinfo = "";
       
  1057 		WriteXMLLineOpeningTag(f, 3, "issue");
       
  1058 		WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(dllIssue.i_list_typeid.at(i)));
       
  1059 		typeinfo = GetDllBreakTypeInfoString(dllIssue.i_list_typeid.at(i));
       
  1060 		if(typeinfo.size() > 0)
       
  1061 			WriteXMLLineOpenClosed(f, 4, "typeinfo", typeinfo);
       
  1062 
       
  1063 		if (dllIssue.i_list_typeid.at(i) == DLL_BASELINE_MISSING )
       
  1064 			WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative");            
       
  1065 		else
       
  1066 			WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break"); 
       
  1067 
       
  1068 		WriteXMLLineOpenClosed(f, 4, "sc_severity", "None");            
       
  1069 
       
  1070 		WriteXMLLineClosingTag(f, 3, "issue");
       
  1071 	}
       
  1072 	writeXMLIssueLibraryFooter(f);
       
  1073 }            
       
  1074 
       
  1075 // ----------------------------------------------------------------------------------------------------------
       
  1076 
       
  1077 void WriteXMLIssueOnlyInCurrentDir(ofstream& f, const string& libname)
       
  1078 {
       
  1079     writeXMLIssueLibraryHeader(f, "", libname);
       
  1080     WriteXMLLineOpeningTag(f, 3, "issue");
       
  1081     WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(ISSUE_ONLY_IN_CURRENTDIR));
       
  1082     WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative");
       
  1083     WriteXMLLineOpenClosed(f, 4, "sc_severity", "Informative");
       
  1084     WriteXMLLineClosingTag(f, 3, "issue");
       
  1085     writeXMLIssueLibraryFooter(f);
       
  1086 }            
       
  1087 
       
  1088 // ----------------------------------------------------------------------------------------------------------
       
  1089 
       
  1090 void WriteIssueListToXML(ofstream& f, const string& libname, const string& curlibname,vector<issue>& issue_list, dll_issue& dllIssue)
       
  1091 {
       
  1092 	if (issue_list.size() > 0 || dllIssue.i_list_typeid.size() > 0)
       
  1093     {
       
  1094         string finallibname(curlibname);
       
  1095         // write header
       
  1096         WriteXMLLineOpeningTag(f, 2, "library");
       
  1097         WriteXMLLineOpenClosed(f, 3, "name", libname);
       
  1098         WriteXMLLineOpenClosed(f, 3, "comparefilename", curlibname);
       
  1099         finallibname=getFilename(finallibname);
       
  1100         // remove any extensions from libname
       
  1101         string::size_type dot_loc = finallibname.find_last_of(".");
       
  1102         if (dot_loc != string::npos)
       
  1103             finallibname = finallibname.substr(0, dot_loc);    
       
  1104         WriteXMLLineOpenClosed(f, 3, "shortname", finallibname);
       
  1105         WriteXMLLineOpenClosed(f, 3, "baseplatform", getPlatform(libname));
       
  1106         WriteXMLLineOpenClosed(f, 3, "currentplatform", getPlatform(curlibname));
       
  1107 
       
  1108         // write all single issues        
       
  1109         for (unsigned int i=0; i<issue_list.size(); i++)
       
  1110         {
       
  1111             WriteXMLLineOpeningTag(f, 3, "issue");
       
  1112             
       
  1113             WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(issue_list.at(i).i_typeid));
       
  1114 
       
  1115             if (issue_list.at(i).i_funcname.length() > 0)          
       
  1116                 WriteXMLLineOpenClosed(f, 4, "funcname", issue_list.at(i).i_funcname);
       
  1117             
       
  1118             if (issue_list.at(i).i_newfuncname.length() > 0)          
       
  1119                 WriteXMLLineOpenClosed(f, 4, "newfuncname", issue_list.at(i).i_newfuncname);
       
  1120             
       
  1121             if (issue_list.at(i).i_funcpos > 0)          
       
  1122                 WriteXMLLineOpenClosed(f, 4, "funcpos", Int2Str(issue_list.at(i).i_funcpos));
       
  1123     
       
  1124             if (issue_list.at(i).i_newfuncpos > 0)          
       
  1125                 WriteXMLLineOpenClosed(f, 4, "newfuncpos", Int2Str(issue_list.at(i).i_newfuncpos));
       
  1126                 
       
  1127             if (issue_list.at(i).i_BC_severity.length() > 0)
       
  1128                 WriteXMLLineOpenClosed(f, 4, "bc_severity", issue_list.at(i).i_BC_severity);
       
  1129 
       
  1130             if (issue_list.at(i).i_SC_severity.length() > 0)          
       
  1131                 WriteXMLLineOpenClosed(f, 4, "sc_severity", issue_list.at(i).i_SC_severity);            
       
  1132             
       
  1133             WriteXMLLineClosingTag(f, 3, "issue");
       
  1134         }
       
  1135 
       
  1136 		
       
  1137 				for (unsigned int i=0; i<dllIssue.i_list_typeid.size(); i++)
       
  1138 				{
       
  1139 					string typeinfo = "";
       
  1140 					WriteXMLLineOpeningTag(f, 3, "issue");
       
  1141 					WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(dllIssue.i_list_typeid.at(i)));
       
  1142 					typeinfo = GetDllBreakTypeInfoString(dllIssue.i_list_typeid.at(i));
       
  1143 					if(typeinfo.size() > 0)
       
  1144 						WriteXMLLineOpenClosed(f, 4, "typeinfo", typeinfo);
       
  1145 
       
  1146 					if (dllIssue.i_list_typeid.at(i) == DLL_BASELINE_MISSING )
       
  1147 						WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative");            
       
  1148 					else
       
  1149 						WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break"); 
       
  1150 
       
  1151 					WriteXMLLineOpenClosed(f, 4, "sc_severity", "None");            
       
  1152 					WriteXMLLineClosingTag(f, 3, "issue");
       
  1153 				}        
       
  1154 
       
  1155 				// finally write footer        
       
  1156 				WriteXMLLineClosingTag(f, 2, "library");        
       
  1157     }
       
  1158 }
       
  1159 
       
  1160 // ----------------------------------------------------------------------------------------------------------
       
  1161