diff -r 000000000000 -r 638b9c697799 apicompatanamdw/compatanalysercmd/libraryanalyser/src/la_analysis.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apicompatanamdw/compatanalysercmd/libraryanalyser/src/la_analysis.cpp Tue Jan 12 14:52:39 2010 +0530 @@ -0,0 +1,1161 @@ +/* +* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Functionality of analysis +* +*/ + + +#include "la.hpp" +#include "la_parser.hpp" +#include "xmlprocessor.hpp" +#include "xmldomainmap.hpp" +#include "xmlsaxparser.hpp" +#include "xmlnode.hpp" +#include "xmlsaxhandler.hpp" +#include "xmlsaxerrorhandler.hpp" + + + +// ---------------------------------------------------------------------------------------------------------- + +typedef XMLSAXHandler > DOCHANDLER; +typedef XMLSAXErrorHandler ERRORHANDLER; +typedef XMLSAXParser PARSER; +typedef XMLProcessor XMLEngine; + + +int XmlTools::initialiseDOM() +{ + try + { + XMLPlatformUtils::Initialize(); + } catch (const XMLException& e ) + { + char* message = _X( e.getMessage() ); + cout << "Error during initialization! :\n" << message << endl ; + _XX(message); + return -1; + } + + DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation( _X("Core") ); + iParser = ((DOMImplementationLS*)impl)->createDOMBuilder( DOMImplementationLS::MODE_SYNCHRONOUS, 0 ); + if ( iParser->canSetFeature( XMLUni::fgDOMValidation, true ) ) + iParser->setFeature( XMLUni::fgDOMValidation, true ); + if ( iParser->canSetFeature( XMLUni::fgDOMNamespaces, true ) ) + iParser->setFeature( XMLUni::fgDOMNamespaces, true ); + if ( iParser->canSetFeature( XMLUni::fgDOMDatatypeNormalization, true ) ) + iParser->setFeature( XMLUni::fgDOMDatatypeNormalization, true ); + + return 0; +} + +void XmlTools::uninitialiseDOM() +{ + iParser->release(); + XMLPlatformUtils::Terminate(); +} + +XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* XmlTools::readFile( const char* aFilename ) +{ + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc; + DOMErrorHandler* myErrorHandler; + + fstream ifile; + bool validate = false; + + string filedoctype; + string doctype("> filedoctype ; + ifile.close(); + + if(doctype.compare(filedoctype) == 0) + validate = true; + + //if document type definition present,create and set error handler to parser, to report any parse errors in issues document. + if(validate) + { + myErrorHandler = new DOMPrintErrorHandler(); + XmlTools::iParser->setErrorHandler(myErrorHandler); + } + + try + { + doc = iParser->parseURI( aFilename ); + } + catch ( const XMLException& e ) + { + char* message = _X( e.getMessage() ); + cout << "Failed to read " << aFilename << ". \"" << message << "\"" << endl ; + _XX( message ); + return NULL; + } + catch ( const DOMException& e ) + { + char* message = _X( e.getMessage() ); + cout << "Failed to read " << aFilename << ". \"" << message << "\"" << endl ; + _XX( message ); + return NULL; + } + catch (...) + { + cout << "Failed to read " << aFilename << ". Unexpected error." << endl ; + return NULL; + } + + //delete the error handler, if set + if(validate) + delete myErrorHandler; + + return doc; +} + +bool DOMPrintErrorHandler::handleError(const DOMError &domError) +{ + // Display whatever error message passed from the parser + if (domError.getSeverity() == DOMError::DOM_SEVERITY_WARNING) + XERCES_STD_QUALIFIER cerr << "\nWarning Message: "; + else if (domError.getSeverity() == DOMError::DOM_SEVERITY_ERROR) + XERCES_STD_QUALIFIER cerr << "\nError Message: "; + else + XERCES_STD_QUALIFIER cerr << "\nFatal Message: "; + + char *msg = XMLString::transcode(domError.getMessage()); + DOMLocator *errorLocator = domError.getLocation(); + XERCES_STD_QUALIFIER cerr<< errorLocator->getLineNumber() << ","; + XERCES_STD_QUALIFIER cerr<< errorLocator->getColumnNumber() << ": "; + XERCES_STD_QUALIFIER cerr<< msg <getElementsByTagName( _X( aTagName ) ); + if ( list == NULL || list->getLength() == 0 ) + return NULL; + else + return (DOMElement*) list->item( 0 ); +} + +int XmlTools::getTagValue( const DOMElement* aParentNode, const char* aTagName, char* aTagValue, int minLen, int maxLen ) +{ + DOMNodeList* list = aParentNode->getElementsByTagName( _X( aTagName ) ); + + strcpy( aTagValue, "" ); + if ( list == NULL || list->getLength() == 0 ) + return -1; + else + { + DOMNode* textNode = list->item( 0 )->getFirstChild(); + if ( textNode == NULL ) + return -1; + + char* text = _X( textNode->getNodeValue() ); + if ( text == NULL ) + return -1; + + int len =(int) strlen( text ); + if ( len < minLen || len > maxLen ) + return -1; + + strcpy( aTagValue, text ); + _XX( text ); + + return 0; + } +} + + +void ParseAndCompareDLLXmlFiles(const string& abaselineXmlFile,const string& acurrentXmlFile) +{ + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* ibaseDoc = NULL; + int currIndx = -1; + int baseIndx = -1; + char dll_name[1024]; + + if ( XmlTools::initialiseDOM() == -1 ) + return ; + + // read report document + ibaseDoc = XmlTools::readFile( abaselineXmlFile.c_str() ); + if ( ibaseDoc == NULL ) + { + XmlTools::uninitialiseDOM(); + return ; + } + + // Parse file + cout << "Gathering dll information... " ; + + //With SAX parser , parse the base xml doc + // Create an instance of our XMLFactory + XMLEngine baseParser(abaselineXmlFile); + // Turn off validation + baseParser.doValidation(false); + baseParser.parse(); + + + //With SAX parser , parse the current xml doc + // Create an instance of our XMLFactory + XMLEngine currParser(acurrentXmlFile); + // Turn off validation + currParser.doValidation(false); + // Parse our XML file + currParser.parse(); + + cout << "Done" <=0 && currIndx>=0) + { + for (unsigned long i = baseIndx; i < totbaseDlls; ++i ) + { + dll_issue issue; + XMLNode base_dlllist = baseRoot.children_[i]; + if ( base_dlllist.childCount() == 0 ) + continue; + string base_dllname = base_dlllist.child("dllname").value(); + base_dllname = getFilename(base_dllname); + + int l; + //char baseVal[5][255]; + char attribs[5][12] = { "uid1", "uid2", "uid3", "sid" ,"capability"}; + + if (base_dllname.size() > 0 ) + { + intializeDllIssue(issue); + issue.l_dllname = base_dllname; + string baseShortName = getFilename(base_dllname); + int curIter; + + for( curIter = currIndx ; curIter < totcurDlls ; curIter++ ) + { + XMLNode curr_dlllist = curRoot.children_[curIter]; + + string cur_dllname = curr_dlllist.child("dllname").value(); + cur_dllname = getFilename(cur_dllname); + vector typeId_list; + + if(stricmp (baseShortName.c_str(),cur_dllname.c_str()) == 0) + { + + for ( l = 0; l < 5; ++ l ) + { + string curVal = curr_dlllist.child(attribs[l]).value(); + string baseVal = base_dlllist.child(attribs[l]).value(); + unsigned int typeId = 0; + + if(l == 4) // capability check + { + unsigned long baseCap =parseHex(baseVal.c_str()); + unsigned long curCap = parseHex(curVal.c_str()); + unsigned long resultCap = baseCap & curCap; + if( baseCap != resultCap) + typeId_list.push_back(DLL_CAPABILITY_CHANGED); + } + else if( curVal.compare(baseVal)!= 0) + { + fillDllIssue(attribs[l], typeId); + typeId_list.push_back(typeId); + } + } + + if(typeId_list.size()> 0 ) + { + issue.i_list_typeid = typeId_list; + _dll_issuelist.push_back(issue); + } + break; + } + } + + if (curIter == totcurDlls ) // missing dll in current xml file + { + issue.i_list_typeid.push_back( DLL_CURRENT_MISSING); + _dll_issuelist.push_back(issue); + } + } + + } + }//end of dll list + + XmlTools::uninitialiseDOM(); +} + +void WriteReportHeader() +{ + _reportf.open(_cl_reportfile.c_str(), ios::trunc); + + if (!_reportf.is_open()) + { + cerr << "ERROR: Cannot open " << _cl_reportfile << " for writing!" << endl; + cerr << "Please check that the directory exists and there are no write permission problems" << endl; + exit(EXIT_CANNOT_WRITE_TO_REPORT_FILE); + } + + WriteXMLLineOpeningTag(_reportf, 0, "?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?"); + WriteXMLLineOpeningTag(_reportf, 0, "?xml-stylesheet type=\"text/xsl\" href=\"BBCResults.xsl\"?"); + WriteXMLLineOpeningTag(_reportf, 0, "bbcresults"); + WriteXMLLineOpeningTag(_reportf, 1, "header"); + + WriteXMLLineOpenClosed(_reportf, 2, "baselineversion", _cl_baselineversion); + WriteXMLLineOpenClosed(_reportf, 2, "currentversion", _cl_currentversion); + + WriteXMLLineOpeningTag(_reportf, 2, "timestamp"); + WriteXMLLineOpenClosed(_reportf, 3, "day", Int2Str(_timenow->tm_mday)); + WriteXMLLineOpenClosed(_reportf, 3, "month", Int2Str(_timenow->tm_mon + 1)); + WriteXMLLineOpenClosed(_reportf, 3, "year", Int2Str(1900 + _timenow->tm_year)); + WriteXMLLineOpenClosed(_reportf, 3, "hour", Int2Str(_timenow->tm_hour)); + WriteXMLLineOpenClosed(_reportf, 3, "minute", Int2Str(_timenow->tm_min)); + WriteXMLLineOpenClosed(_reportf, 3, "second", Int2Str(_timenow->tm_sec)); + WriteXMLLineClosingTag(_reportf, 2, "timestamp"); + + WriteXMLLineOpenClosed(_reportf, 2, "laversion", LA_VERSION); + WriteXMLLineOpenClosed(_reportf, 2, "formatversion", LA_REPORT_FORMAT_VERSION); + + WriteXMLLineOpeningTag(_reportf, 2, "cmdlineparms"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "toolchain"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _toolchain_name); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselinelibdir"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselinelibdir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentlibdir"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentlibdir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselinedlldir"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselinedlldir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentdlldir"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentdlldir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + if(_cl_baselinedlldir.empty() || _cl_currentdlldir.empty()) + { + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "warning"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue","Required parameters for checking dll properties not specified. Compatibility Breaks in dll are not checked." ); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + } + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "baselineversion"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_baselineversion); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "currentversion"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_currentversion); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "reportfile"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_reportfile); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "tools"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_toolsdir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "temp"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_tempdir); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "cfilt"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_cfiltloc); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineOpeningTag(_reportf, 3, "parm"); + WriteXMLLineOpenClosed(_reportf, 4, "pname", "set"); + WriteXMLLineOpenClosed(_reportf, 4, "pvalue", _cl_set); + WriteXMLLineClosingTag(_reportf, 3, "parm"); + + WriteXMLLineClosingTag(_reportf, 2, "cmdlineparms"); + + WriteXMLLineOpenClosed(_reportf, 2, "knownissuesversion", ""); + + WriteXMLLineClosingTag(_reportf, 1, "header"); + WriteXMLLineOpeningTag(_reportf, 1, "issuelist"); +} + +// ---------------------------------------------------------------------------------------------------------- + +void GenerateAndWriteIssueList() +{ + int total_files = _lib_files_baseline.size(); + int current_files = 0; + cout <<"Total baseline files "<< _lib_files_baseline.size() << endl; + cout <<"Total current files "<< _lib_files_current.size() << endl; + + vector::const_iterator itr; + for (unsigned int i=0; i<_lib_files_current.size(); i++) + { + bool exists = false; + // check if the same lib exists in baselinedir + for(itr = _lib_dirs_baseline.begin(); itr != _lib_dirs_baseline.end(); itr++) + { + if (FileExists(*itr + getFilename(_lib_files_current.at(i)))) + { + exists = true; + break; + } + } + if(!exists) + { + total_files++; + } + } + cout <<"Total files to be processed "<< total_files << endl; + //vector dll_issuelist; + + dll_issue reportdll; + string dllname; + + if(_baselinedllfile.size() > 0 && _currentdllfile.size() > 0) + { + ParseAndCompareDLLXmlFiles(_baselinedllfile,_currentdllfile ); + } + + unsigned int dllIssueCount = _dll_issuelist.size(); + + // first go through all libs in the baseline set + for (unsigned int i=0; i<_lib_files_baseline.size(); i++) + { + unsigned int k; + vector::iterator itr = _lib_files_current.end(); + bool exists = false; + + //check if the same dll is present in exe_issue, if yes then add it to final report + intializeDllIssue(reportdll); + for(unsigned int indx = 0; indx < dllIssueCount; indx++) + { + dll_issue lIssue; + lIssue = _dll_issuelist.at(indx); + if(StringICmpFileNamesWithoutExtension(getFilename(lIssue.l_dllname),getFilename(_lib_files_baseline.at(i))) == 0) + { + reportdll = lIssue; + break; + } + } + + + // check if the same lib exists in currentdir + for(k = 0; k < _lib_dirs_current.size(); k++) + { + string file = _lib_dirs_current.at(k) + getFilename(_lib_files_baseline.at(i)); + if (FileExists( file )) + { + for(itr=_lib_files_current.begin() ; itr != _lib_files_current.end() ; ++itr) + { + if(StringICmp(file,*itr)== 0) + { + exists = true; + break; + } + } + if(exists) + break; + } + } + + // check if the same lib exists in currentdir + if (!exists) + { + cout.precision(0); + cout << "\nAnalysing files (" << current_files+1 << "/" << total_files << "): " << _lib_files_baseline.at(i) << endl; + + WriteXMLIssueOnlyInBaselineDir(_reportf, _lib_files_baseline.at(i),reportdll); + } + else + { + cout.precision(0); + cout << "\nAnalysing files (" << current_files+1 << "/" << total_files << "): " << _lib_files_baseline.at(i) << " => " << *itr << endl; + // both files are available, now get the symbol table and do the comparision process + vector symbol_table_baseline; + vector symbol_table_current; + + // get the symbol tables of the libraries + if (_cl_use_gcc) + { + GetSymbolTableWithNM(_gcc_nm_location, _lib_files_baseline.at(i), symbol_table_baseline); + GetSymbolTableWithNM(_gcc_nm_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current); + } + else if (_cl_use_gcce) + { + if (_cl_use_libs) + { + GetSymbolTableWithNM(_gcce_nm_location, _lib_files_baseline.at(i), symbol_table_baseline); + GetSymbolTableWithNM(_gcce_nm_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current); + } + else + { + GetSymbolTableWithReadelf(_gcce_readelf_location, _gcce_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline); + GetSymbolTableWithReadelf(_gcce_readelf_location, _gcce_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current); + } + } + else if (_cl_use_rvct) + { + if (_cl_use_libs) + { + GetSymbolTableWithArmar(_rvct_armar_location, _rvct_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline); + GetSymbolTableWithArmar(_rvct_armar_location, _rvct_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current); + } + else + { + GetSymbolTableWithFromelf(_rvct_fromelf_location, _rvct_cfilt_location, _lib_files_baseline.at(i), symbol_table_baseline); + GetSymbolTableWithFromelf(_rvct_fromelf_location, _rvct_cfilt_location, *itr /*_lib_files_current.at(i)*/, symbol_table_current); + } + } + + // create a vector to store all issues of this library + vector issue_list; + //Local variable to store severity of the issue + TypeOfSeverity severity = NO_BREAK; + // create and init vectors to store ordinal state + vector matched_baseline; + vector checked_baseline; + vector matched_current; + vector checked_current; + vector map_severity; + + for (unsigned int j=0; j checked_current.size()) + { + for (unsigned int j=checked_current.size(); j::const_iterator itr = _lib_dirs_baseline.begin(); + // check if the same lib exists in baselinedir + for(;itr != _lib_dirs_baseline.end(); itr++) + { + if (FileExists(*itr + getFilename( _lib_files_current.at(i)) )) + { + exists = true; + break; + } + } + if(!exists) + { + current_files++; + cout.precision(0); + cout << "\nAnalysing files (" << current_files << "/" << total_files << "): " << _lib_files_current.at(i) << endl; + + // only in currentdir + WriteXMLIssueOnlyInCurrentDir(_reportf, _lib_files_current.at(i)); + } + } + cout << "\n---------------------------------------------"; + cout << "\nFinished"; + cout << "\nTotal Files analysed : " << total_files; + cout << "\n---------------------------------------------"; +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteReportFooter() +{ + // generate the footer of XML file + WriteXMLLineClosingTag(_reportf, 1, "issuelist"); + WriteXMLLineClosingTag(_reportf, 0, "bbcresults"); + + // close writing to the report file + _reportf.close(); +} + +// ---------------------------------------------------------------------------------------------------------- + +void AppendToIssueListCaseMoved(vector& issueList, const string& funcname, int funcpos, int newfuncpos,TypeOfSeverity severity) +{ + issue i; + string bc_severity = ""; + string sc_severity = ""; + getSeverityString(severity,bc_severity,sc_severity); + + i.i_typeid = ISSUE_MOVED; + i.i_funcname = funcname; + i.i_newfuncname = ""; + i.i_funcpos = funcpos; + i.i_newfuncpos = newfuncpos; + i.i_BC_severity = bc_severity; + i.i_SC_severity = sc_severity; + + issueList.push_back(i); +} + +// ---------------------------------------------------------------------------------------------------------- + +void AppendToIssueListCaseRemoved(vector& issue_list, const string& funcname, int funcpos,TypeOfSeverity severity) +{ + issue i; + string bc_severity = ""; + string sc_severity = ""; + getSeverityString(severity,bc_severity,sc_severity); + + i.i_typeid = ISSUE_REMOVED; + i.i_funcname = funcname; + i.i_newfuncname = ""; + i.i_funcpos = funcpos; + i.i_newfuncpos = 0; + i.i_BC_severity = bc_severity; + i.i_SC_severity = sc_severity; + + issue_list.push_back(i); +} + +// ---------------------------------------------------------------------------------------------------------- + +void AppendToIssueListCaseInserted(vector& issue_list, const string& newfuncname, int newfuncpos,TypeOfSeverity severity) +{ + issue i; + string bc_severity = ""; + string sc_severity = ""; + getSeverityString(severity,bc_severity,sc_severity); + + i.i_typeid = ISSUE_INSERTED; + i.i_funcname = ""; + i.i_newfuncname = newfuncname; + i.i_funcpos = 0; + i.i_newfuncpos = newfuncpos; + i.i_BC_severity = bc_severity; + i.i_SC_severity = sc_severity; + + issue_list.push_back(i); +} + +// ---------------------------------------------------------------------------------------------------------- + +void AppendToIssueListCaseModified(vector& issue_list, const string& funcname, const string& newfuncname, int funcpos,TypeOfSeverity severity) +{ + issue i; + string bc_severity = ""; + string sc_severity = ""; + getSeverityString(severity,bc_severity,sc_severity); + + i.i_typeid = ISSUE_MODIFIED; + i.i_funcname = funcname; + i.i_newfuncname = newfuncname; + i.i_funcpos = funcpos; + i.i_newfuncpos = 0; + i.i_BC_severity = bc_severity; + i.i_SC_severity = sc_severity; + + issue_list.push_back(i); +} + +// ---------------------------------------------------------------------------------------------------------- + +void AppendToIssueListCaseAdded(vector& issue_list, const string& newfuncname, int newfuncpos,TypeOfSeverity severity) +{ + issue i; + string bc_severity = ""; + string sc_severity = ""; + getSeverityString(severity,bc_severity,sc_severity); + + i.i_typeid = ISSUE_ADDED; + i.i_funcname = ""; + i.i_newfuncname = newfuncname; + i.i_funcpos = 0; + i.i_newfuncpos = newfuncpos; + i.i_BC_severity = bc_severity; + i.i_SC_severity = sc_severity; + + issue_list.push_back(i); +} + +// ---------------------------------------------------------------------------------------------------------- + +bool IssueCompare(const issue& left, const issue& right) +{ + if (left.i_funcpos > 0 && right.i_funcpos > 0) + { + if (left.i_funcpos == right.i_funcpos && left.i_newfuncpos > 0 && right.i_newfuncpos > 0) + return left.i_newfuncpos < right.i_newfuncpos; + else + return left.i_funcpos < right.i_funcpos; + } + + else if (left.i_funcpos == 0 && right.i_funcpos > 0) + { + if (left.i_newfuncpos == right.i_funcpos) + return left.i_funcpos < right.i_newfuncpos; + else + return left.i_newfuncpos < right.i_funcpos; + } + + else if (left.i_funcpos > 0 && right.i_funcpos == 0) + { + if (left.i_funcpos == right.i_newfuncpos) + return left.i_newfuncpos < right.i_funcpos; + else + return left.i_funcpos < right.i_newfuncpos; + } + + else // if (left.i_funcpos == 0 && right.i_funcpos == 0) + { + return left.i_newfuncpos < right.i_newfuncpos; + } +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteXMLLineOpenClosed(ofstream& f, unsigned int tabstops, const string& element, const string& data) +{ + string tabs(tabstops, REPORT_TAB_CHAR); + string xmldata(data); + + // replace & -> ä + string::size_type i=0; + while ((i=xmldata.find("&", i)) != string::npos) + { + xmldata.replace(i, 1, "&"); + i++; + } + + // replace < -> < + i=0; + while ((i=xmldata.find("<", i)) != string::npos) + xmldata.replace(i, 1, "<"); + + // replace > -> > + i=0; + while ((i=xmldata.find(">", i)) != string::npos) + xmldata.replace(i, 1, ">"); + + + f << tabs << "<" << element << ">" << xmldata << "" << endl; +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteXMLLineOpeningTag(ofstream& f, unsigned int tabstops, const string& element) +{ + string tabs(tabstops, REPORT_TAB_CHAR); + + f << tabs << "<" << element << ">" << endl; +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteXMLLineClosingTag(ofstream& f, unsigned int tabstops, const string& element) +{ + string tabs(tabstops, REPORT_TAB_CHAR); + + f << tabs << "" << endl; +} + +// ---------------------------------------------------------------------------------------------------------- + +void writeXMLIssueLibraryHeader(ofstream& f, const string& libname, const string& curlibname) +{ + + WriteXMLLineOpeningTag(f, 2, "library"); + WriteXMLLineOpenClosed(f, 3, "name", libname); + WriteXMLLineOpenClosed(f, 3, "comparefilename", curlibname); + + string finallibname(curlibname); + if (finallibname.empty()) + finallibname=libname; + finallibname=getFilename(finallibname); + // remove any extensions from libname + string::size_type dot_loc = finallibname.find_last_of("."); + if (dot_loc != string::npos) + finallibname = finallibname.substr(0, dot_loc); + WriteXMLLineOpenClosed(f, 3, "shortname", finallibname); + WriteXMLLineOpenClosed(f, 3, "baseplatform", getPlatform(libname)); + WriteXMLLineOpenClosed(f, 3, "currentplatform", getPlatform(curlibname)); +} + +// ---------------------------------------------------------------------------------------------------------- + +void writeXMLIssueLibraryFooter(ofstream& f) +{ + WriteXMLLineClosingTag(f, 2, "library"); +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteXMLIssueOnlyInBaselineDir(ofstream& f, const string& libname, dll_issue& dllIssue) +{ + writeXMLIssueLibraryHeader(f, libname, ""); + WriteXMLLineOpeningTag(f, 3, "issue"); + WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(ISSUE_ONLY_IN_BASELINEDIR)); + WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break"); + WriteXMLLineOpenClosed(f, 4, "sc_severity", "SC Break"); + WriteXMLLineClosingTag(f, 3, "issue"); + for(unsigned int i =0; i< dllIssue.i_list_typeid.size(); i++ ) + { + string typeinfo = ""; + WriteXMLLineOpeningTag(f, 3, "issue"); + WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(dllIssue.i_list_typeid.at(i))); + typeinfo = GetDllBreakTypeInfoString(dllIssue.i_list_typeid.at(i)); + if(typeinfo.size() > 0) + WriteXMLLineOpenClosed(f, 4, "typeinfo", typeinfo); + + if (dllIssue.i_list_typeid.at(i) == DLL_BASELINE_MISSING ) + WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative"); + else + WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break"); + + WriteXMLLineOpenClosed(f, 4, "sc_severity", "None"); + + WriteXMLLineClosingTag(f, 3, "issue"); + } + writeXMLIssueLibraryFooter(f); +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteXMLIssueOnlyInCurrentDir(ofstream& f, const string& libname) +{ + writeXMLIssueLibraryHeader(f, "", libname); + WriteXMLLineOpeningTag(f, 3, "issue"); + WriteXMLLineOpenClosed(f, 4, "typeid", Int2Str(ISSUE_ONLY_IN_CURRENTDIR)); + WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative"); + WriteXMLLineOpenClosed(f, 4, "sc_severity", "Informative"); + WriteXMLLineClosingTag(f, 3, "issue"); + writeXMLIssueLibraryFooter(f); +} + +// ---------------------------------------------------------------------------------------------------------- + +void WriteIssueListToXML(ofstream& f, const string& libname, const string& curlibname,vector& issue_list, dll_issue& dllIssue) +{ + if (issue_list.size() > 0 || dllIssue.i_list_typeid.size() > 0) + { + string finallibname(curlibname); + // write header + WriteXMLLineOpeningTag(f, 2, "library"); + WriteXMLLineOpenClosed(f, 3, "name", libname); + WriteXMLLineOpenClosed(f, 3, "comparefilename", curlibname); + finallibname=getFilename(finallibname); + // remove any extensions from libname + string::size_type dot_loc = finallibname.find_last_of("."); + if (dot_loc != string::npos) + finallibname = finallibname.substr(0, dot_loc); + WriteXMLLineOpenClosed(f, 3, "shortname", finallibname); + WriteXMLLineOpenClosed(f, 3, "baseplatform", getPlatform(libname)); + WriteXMLLineOpenClosed(f, 3, "currentplatform", getPlatform(curlibname)); + + // write all single issues + for (unsigned int i=0; i 0) + WriteXMLLineOpenClosed(f, 4, "funcname", issue_list.at(i).i_funcname); + + if (issue_list.at(i).i_newfuncname.length() > 0) + WriteXMLLineOpenClosed(f, 4, "newfuncname", issue_list.at(i).i_newfuncname); + + if (issue_list.at(i).i_funcpos > 0) + WriteXMLLineOpenClosed(f, 4, "funcpos", Int2Str(issue_list.at(i).i_funcpos)); + + if (issue_list.at(i).i_newfuncpos > 0) + WriteXMLLineOpenClosed(f, 4, "newfuncpos", Int2Str(issue_list.at(i).i_newfuncpos)); + + if (issue_list.at(i).i_BC_severity.length() > 0) + WriteXMLLineOpenClosed(f, 4, "bc_severity", issue_list.at(i).i_BC_severity); + + if (issue_list.at(i).i_SC_severity.length() > 0) + WriteXMLLineOpenClosed(f, 4, "sc_severity", issue_list.at(i).i_SC_severity); + + WriteXMLLineClosingTag(f, 3, "issue"); + } + + + for (unsigned int i=0; i 0) + WriteXMLLineOpenClosed(f, 4, "typeinfo", typeinfo); + + if (dllIssue.i_list_typeid.at(i) == DLL_BASELINE_MISSING ) + WriteXMLLineOpenClosed(f, 4, "bc_severity", "Informative"); + else + WriteXMLLineOpenClosed(f, 4, "bc_severity", "BBC Break"); + + WriteXMLLineOpenClosed(f, 4, "sc_severity", "None"); + WriteXMLLineClosingTag(f, 3, "issue"); + } + + // finally write footer + WriteXMLLineClosingTag(f, 2, "library"); + } +} + +// ---------------------------------------------------------------------------------------------------------- +