apicompatanamdw/compatanalysercmd/headeranalyser/src/ReportGenerator.cpp
changeset 0 638b9c697799
child 3 ebe3f8f03b59
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/apicompatanamdw/compatanalysercmd/headeranalyser/src/ReportGenerator.cpp	Tue Jan 12 14:52:39 2010 +0530
@@ -0,0 +1,1164 @@
+/*
+* Copyright (c) 2006-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:  
+*
+*/
+
+
+#include "CmdGlobals.h"
+#ifdef __WIN__
+#pragma warning(disable:4786)
+#endif
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/framework/LocalFileFormatTarget.hpp>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <algorithm>
+#include <time.h>
+
+#include "ReportGeneratorConstants.h"
+#include "CmdGlobals.h"
+#include "ReportIssue.h"
+#include "XMLModuleErrorHandler.h"
+#include "HAException.h"
+#include "Utils.h"
+#include "Issues.h"
+#include "BBCFileUtils.h"
+using namespace std;
+
+extern vector<pair<string,pair<string,string> > > HeaderInfoList; // vector<pair< headerfile name, pair<API name, API category>>>
+
+XERCES_CPP_NAMESPACE_USE
+
+
+const char* KXMLStyleSheet = "xml-stylesheet";
+
+// Style sheet filename
+const char* KXMLXSL = "type=\"text/xsl\" href=\"BBCResults.xsl\"";
+// Base64 coding characters
+const char* KBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-";
+
+#include "ReportGenerator.h"
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::ReportGenerator
+// ----------------------------------------------------------------------------
+//
+ReportGenerator::ReportGenerator(string aOutputFile) 
+: 
+iOutputFile(aOutputFile), 
+iIssueId(0),
+iDOMDocument(0),
+iDOMRoot(0)
+{
+	// START -- Support for file checksum and comments
+	unsigned long crc;
+	iCrcTable = new unsigned long[256];
+	for ( int i = 0; i <= 255 ; i++ )
+	{
+		crc = i;
+		for ( int j = 8 ; j > 0; j-- )
+		{
+			if ( crc & 1 )
+				crc = ( crc >> 1 ) ^ 0xEDB88320L;
+			else
+				crc >>= 1;
+		}
+		iCrcTable[i] = crc;
+	}
+	// END -- Support for file checksum and comments
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::~ReportGenerator
+// ----------------------------------------------------------------------------
+//
+ReportGenerator::~ReportGenerator()
+{
+	// START -- Support for file checksum and comments
+	delete iCrcTable;
+	iCrcTable = NULL;
+	// END -- Support for file checksum and comments
+	if( iDOMDocument )
+	{
+		iDOMDocument->release();
+	}
+	for( issueMap::iterator i = iIssueMap.begin(); i != iIssueMap.end(); ++i )
+	{
+		delete i->second;
+		i->second = 0;
+	}
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::setXSL
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::setXSL(string aXSLFilename, bool aIncludeInXML)
+{
+    iXSLFile = aXSLFilename;
+    iEmbedXSL = aIncludeInXML;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::setDTD
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::setDTD(string aDTDFilename, bool aIncludeInDTD)
+{
+    iDTDFile = aDTDFilename;
+    iEmbedDTD = aIncludeInDTD;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::startReport
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::startReport()
+{
+    initialiseDOM();
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::finishReport
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::finishReport()
+{
+    DOMElement* issuelist = createIssueListNode();
+    iDOMRoot->appendChild(issuelist);
+    dumpDOMToFile();
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::loadStringTables
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::loadStringTables(string aFilename)
+{
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::setCmdLineParms
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::setCmdLineParms(map<string, string> aParms)
+{
+    map<string, string>::iterator begin = aParms.begin();
+    map<string, string>::iterator end = aParms.end();
+    while (begin != end)
+    {
+        iParams.insert(*begin);
+        begin++;
+    }
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::getCmdLineParm
+// ----------------------------------------------------------------------------
+//
+string ReportGenerator::getCmdLineParm(string aParm)
+{
+    map<string, string>::iterator begin = iParams.find(aParm);
+    if (begin != iParams.end())
+    {
+        return (*begin).second;
+    }
+    else
+    {
+        return "Not specified";
+    }
+}
+
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::setVersions
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::setVersions(string aBaseline, string aCurrent)
+{
+    iBaselineVersion = aBaseline;
+    iCurrentVersion = aCurrent;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::addIssue
+// ----------------------------------------------------------------------------
+//
+int ReportGenerator::addIssue(ReportIssue* aIssue)
+{
+	aIssue->iId = iIssueId++;
+	
+    string key = "<";
+    key += aIssue->HeaderFile();
+    key += "><";
+    key += aIssue->CompareFileName();
+    key += ">";
+
+    issueMapIterator it = iIssueMap.find(key);
+    if (it != iIssueMap.end())
+    {
+		bool lineInfoNeed = true;
+        // header entry is present in the report. append the issue to the header issue list
+        issueVector* v = it->second;
+		issueVector::iterator iv_it=v->begin();
+		bool notAnalysed = false;
+		 for (; iv_it != v->end(); ++iv_it)
+		 {
+			 ReportIssue* issue = iv_it->second;
+
+			 TIssueIdentity id = issue->IdentityId();
+			 TIssueType type = issue->TypeId();
+			 if( id == EIssueIdentityFile && type == EIssueTypeEmpty)
+			 {
+				 notAnalysed = true;
+				 lineInfoNeed = issue->LineInfoNeeded();
+				 break;
+			 }
+		}
+		if(lineInfoNeed == false)
+		{
+			aIssue->SetLineNumber(0);
+		}
+        if( v->insert(pair<const ReportIssue*, ReportIssue*>(aIssue,aIssue)).second == false )
+        {
+            return -1;
+        }
+    } else
+    {
+        // header entry is not present in the report. create an entry for the header with this issue
+        issueVector* v = new issueVector();
+        v->insert(pair<const ReportIssue*, ReportIssue*>(aIssue,aIssue));
+        issueEntry entry(key,v);
+        iIssueMap.insert(entry);
+    }
+    
+	return iIssueId-1;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::addIssue
+// ----------------------------------------------------------------------------
+//
+int ReportGenerator::addIssue(const string& aFile, 
+                const string& aFQName, const TIssueIdentity& aIdentityId, 
+                const TIssueType& aTypeId, const TBCSeverity& aBCSeverityId, 
+                const TSCSeverity& aSCSeverityId, const string& aIgnoreInformation, 
+                int aLineNumber, const string& aCompareFileName, const string& aCompilationError, bool alineNoNeeded )
+{
+	string fqName = aFQName;
+	int loc = fqName.find(__FUN_MANGLED__);
+	if(loc != -1)
+	{
+	fqName = fqName.substr(0,loc);
+	}
+    ReportIssue* issue = new ReportIssue(0, aFile, fqName, 
+			aIdentityId, aTypeId, aBCSeverityId, aSCSeverityId, aIgnoreInformation, 
+            aLineNumber, aCompareFileName, aCompilationError, alineNoNeeded );
+
+    /*return*/
+    int ret = addIssue(issue);
+    if( ret == -1)
+    {
+        delete issue;
+    }
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::dumpXSLToFile
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::dumpXSLToFile()
+{
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::dumpDTDToFile
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::dumpDTDToFile()
+{
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::dumpDOMToFile
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::dumpDOMToFile()
+{
+    XMLCh* features = _X("Core");
+    DOMImplementation* imp =  DOMImplementationRegistry::getDOMImplementation(features);
+    _XX(features);
+    DOMWriter* writer = ((DOMImplementationLS*)imp)->createDOMWriter();
+    
+    writer->setFeature( XMLUni::fgDOMWRTFormatPrettyPrint,true);
+    DOMErrorHandler* errorHandler = new XMLModuleErrorHandler();
+    // Set error handler
+    writer->setErrorHandler(errorHandler);
+    XMLCh* tempfilename = XMLString::transcode(iOutputFile.c_str());
+    XMLFormatTarget* ft = new LocalFileFormatTarget(tempfilename);
+    writer->writeNode(ft, *iDOMDocument);
+    XMLString::release(&tempfilename);
+    delete ft;
+    writer->release();
+    delete errorHandler;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::generateVersionIdNodes
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::generateVersionIdNodes()
+{
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::initialiseDOM
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::initialiseDOM()
+{    
+    XMLCh * features = _X("Core");
+    DOMImplementation* imp =  DOMImplementationRegistry::getDOMImplementation(features);
+    _XX(features);
+    if (imp != NULL)
+    {
+        try
+        {
+            XMLCh * repRoot = _X(NODE_REPORTROOT);
+            DOMDocument* doc = imp->createDocument(NULL, repRoot, NULL);
+		        _XX(repRoot);
+		        if( iDOMDocument )
+		        {
+		            iDOMDocument->release();				
+		            iDOMDocument = 0;
+		        }
+            iDOMDocument = doc;
+
+            XMLCh * stylesheet = XMLString::transcode(KXMLStyleSheet);
+            XMLCh * xsl = XMLString::transcode(KXMLXSL);
+            
+            // Style sheet is inserted to DOM document
+            iDOMDocument->insertBefore( 
+                iDOMDocument->createProcessingInstruction(
+                  stylesheet,
+                    xsl
+                ),
+                iDOMDocument->getDocumentElement()
+            ); 
+            XMLString::release(&stylesheet);
+            XMLString::release(&xsl);
+                
+            iDOMRoot = iDOMDocument->getDocumentElement();
+            // Header node created
+            DOMElement* header = createHeaderNode();
+            iDOMRoot->appendChild(header);
+        } catch (const XMLException& /*e*/)
+        {
+            throw HAException("Error initialising the DOM Document");
+        }
+    }
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::uninitialiseDOM
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::uninitialiseDOM()
+{
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createOpenNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createOpenNode(const char* aNodeName)
+{
+    DOMElement* ret = NULL;
+    XMLCh* ch = XMLString::transcode(aNodeName);
+    ret = iDOMDocument->createElement(ch);
+	XMLString::release(&ch);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createHeaderNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createHeaderNode()
+{
+    DOMElement* ret = NULL;
+    ret = createOpenNode(NODE_HEADER);
+    vector<DOMElement*> childvec;
+
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_BASELINEVERSION, iBaselineVersion.c_str()));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_CURRENTVERSION, iCurrentVersion.c_str()));
+    childvec.push_back(createTimestampNode());
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_HAVERSION, HEADER_ANALYSER_VERSION));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_FORMATVERSION, HEADER_ANALYSER_REPORT_VERSION));
+    childvec.push_back(createCmdLineNode());
+
+    appendChildrenToNode(ret, childvec);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::removeRemovedSubClasses
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::removeRemovedSubClasses()
+{
+    issueMapIterator it = iIssueMap.begin(); 
+    for (; it != iIssueMap.end();++it)
+    {
+        issueVector* iv = it->second;
+		issueVector::iterator iv_it=iv->begin();
+
+        for (; iv_it != iv->end(); ++iv_it)
+        {
+            ReportIssue* issue = iv_it->second;
+
+			TIssueIdentity id = issue->IdentityId();
+			TIssueType type = issue->TypeId();
+			
+			//Do not process macros or other than issues type "removed"
+			if ( EIssueTypeRemoval == type && EIssueIdentityMacro != id )
+			{
+				string fqname = issue->FQName();
+				fqname += "::";
+				
+				issueVector::iterator iv_it2=iv_it;
+				++iv_it2;
+		
+				for (; iv_it2 != iv->end(); ++iv_it2)
+				{
+					ReportIssue* issue2 = iv_it2->second;
+					string fqname2 = issue2->FQName();
+					
+					//If the issue is inside removed class it can be removed from list
+					if ( 0 == fqname2.compare(0, fqname.length(), fqname) )
+					{
+						issueVector::iterator iv_it3 = iv_it2;
+						--iv_it2;
+						iv->erase(iv_it3);
+					} else //No more issues inside removed class so break
+					{
+						break;
+					}
+				}
+			}
+		}
+
+	}
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::functionMapping
+// ----------------------------------------------------------------------------
+//
+TIssueIdentity ReportGenerator::functionMapping(const vector<TIssueIdentity> & ids)
+{
+
+	TIssueIdentity ret = EIssueIdentityExportedFunction;
+
+	if (ids.size() == 1)
+	{
+		ret = ids[0];
+	}
+	else if (ids.size() == 3)
+	{
+		ret = EIssueIdentityExportedVirtualInlineFunction;
+	}
+	else
+	{
+		if (  (EIssueIdentityExportedFunction == ids[0] && EIssueIdentityVirtualFunction == ids[1]) ||
+				(EIssueIdentityExportedFunction == ids[1] && EIssueIdentityVirtualFunction == ids[0]) )
+		{
+			ret = EIssueIdentityExportedVirtualFunction;
+		} else	if (  (EIssueIdentityExportedFunction == ids[0] && EIssueIdentityInlineFunction == ids[1]) ||
+				(EIssueIdentityExportedFunction == ids[1] && EIssueIdentityInlineFunction == ids[0]) )
+		{
+			ret = EIssueIdentityExportedInlineFunction;
+		} else if (  (EIssueIdentityInlineFunction == ids[0] && EIssueIdentityVirtualFunction == ids[1]) ||
+				(EIssueIdentityInlineFunction == ids[1] && EIssueIdentityVirtualFunction == ids[0]) )
+		{
+			ret = EIssueIdentityVirtualInlineFunction;
+		}
+	}
+	return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::mergeFunctionIssues
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::mergeFunctionIssues()
+{
+    issueMapIterator it = iIssueMap.begin(); 
+    for (; it != iIssueMap.end();++it)
+    {
+        issueVector* iv = it->second;
+		issueVector::iterator iv_it=iv->begin();
+
+        for (; iv_it != iv->end(); ++iv_it)
+        {
+            ReportIssue* issue = iv_it->second;
+
+			TIssueIdentity id = issue->IdentityId();
+			TIssueType type = issue->TypeId();
+			
+			//Process functions only
+			if (    
+				EIssueIdentityExportedFunction == id ||
+				EIssueIdentityInlineFunction == id ||
+				EIssueIdentityVirtualFunction == id 
+			   )
+			{
+				vector<TIssueIdentity> identities;
+				identities.reserve(3);
+				string fqname = issue->FQName();
+				identities.push_back(issue->IdentityId());
+				issueVector::iterator iv_it2=iv_it;
+				++iv_it2;
+		
+				TBCSeverity bcseverity = issue->BCSeverity();
+				TSCSeverity scseverity = issue->SCSeverity();
+
+				for (; iv_it2 != iv->end(); ++iv_it2)
+				{
+					ReportIssue* issue2 = iv_it2->second;
+					string fqname2 = issue2->FQName();
+					TIssueType type2 = issue2->TypeId();
+					
+					//If the issue has same type and it is for the same function
+					if ( (fqname2 == fqname) && (type2 == type) )
+					{
+						if ( issue2->BCSeverity() < bcseverity )
+						{
+							bcseverity = issue2->BCSeverity();
+						}
+						if ( issue2->SCSeverity() < scseverity )
+						{
+							scseverity = issue2->SCSeverity();
+						}
+						identities.push_back(issue2->IdentityId());
+						issueVector::iterator iv_it3 = iv_it2;
+						--iv_it2;
+						iv->erase(iv_it3);
+					} 
+				}
+				if (identities.size() > 0)
+				{
+					issue->SetIdentityId( functionMapping(identities) );
+					issue->SetBCSeverity(bcseverity);			
+					issue->SetSCSeverity(scseverity);
+				}
+			}
+		}
+
+	}
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::preprocessIssueList
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::preprocessIssueList()
+{
+	removeRemovedSubClasses();
+	mergeFunctionIssues();
+}
+
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createIssueListNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createIssueListNode()
+{
+    preprocessIssueList();
+
+    DOMElement* ret = NULL;
+	bool apiFound = false;
+    ret = createOpenNode(NODE_ISSUELIST);
+    issueMapIterator it = iIssueMap.begin();
+    while (it != iIssueMap.end())
+    {
+		apiFound = false;
+        issueVector* iv = it->second;
+        issueVector::const_iterator iv_it = iv->begin();
+
+        DOMElement* headerfilenode = createOpenNode(NODE_ISSUELIST_HEADERFILE);
+        DOMElement* filenamenode = createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_FILENAME, iv_it->second->HeaderFile().c_str());
+        headerfilenode->appendChild(filenamenode);
+                 
+        // Append compared file here, Check from first Report issue, what was compare file name
+        DOMElement* compareFileNameNode = createSimpleTextNode(
+            NODE_ISSUELIST_HEADERFILE_COMPARE_FILENAME, iv_it->second->CompareFileName().c_str());
+
+        headerfilenode->appendChild( compareFileNameNode );
+        
+        // START -- Support for file checksum and comments
+        DOMElement* statusNode = createSimpleTextNode( NODE_ISSUELIST_HEADERFILE_STATUS, "" );
+        headerfilenode->appendChild( statusNode );
+        DOMElement* commentNode = createSimpleTextNode( NODE_ISSUELIST_HEADERFILE_COMMENT, "" );
+        headerfilenode->appendChild( commentNode );
+
+		// If Global header list is found with API info, then fill those in report file.
+		for(unsigned int i = 0; i < HeaderInfoList.size(); i++ )
+		{
+			if(stricmp (HeaderInfoList.at(i).first.c_str(), iv_it->second->CompareFileName().c_str()) == 0)
+			{
+				DOMElement* apiNode = createAPIAttributeNode( NODE_ISSUELIST_HEADERFILE_ISSUE_APISTRING,
+					                      HeaderInfoList.at(i).second.first.c_str(), HeaderInfoList.at(i).second.second.c_str() );
+				headerfilenode->appendChild(apiNode);
+				apiFound = true;
+			}
+			else if (stricmp( HeaderInfoList.at(i).first.c_str(), iv_it->second->HeaderFile().c_str()) == 0)
+			{
+				DOMElement* apiNode = createAPIAttributeNode( NODE_ISSUELIST_HEADERFILE_ISSUE_APISTRING,
+					HeaderInfoList.at(i).second.first.c_str(), HeaderInfoList.at(i).second.second.c_str() );
+				headerfilenode->appendChild(apiNode);
+				apiFound = true;
+			}
+			if( apiFound == true )
+				break;
+		}
+		// Global list is present, but the header has not been found from the list, then add api info for the header as "Unknown"
+		if( apiFound == false && HeaderInfoList.size() > 0)
+		{
+			DOMElement* apiNode = createAPIAttributeNode( NODE_ISSUELIST_HEADERFILE_ISSUE_APISTRING,
+				NODE_ISSUELIST_HEADERFILE_APIINFO_UNKNOWN, NODE_ISSUELIST_HEADERFILE_APIINFO_UNKNOWN );
+			headerfilenode->appendChild(apiNode);
+		}
+		//else no API info will be available for any header.
+        
+        char checksum[14];
+        if ( strlen( iv_it->second->CompareFileName().c_str() ) > 0) 
+            getFileCRC( iv_it->second->CompareFileName().c_str(), checksum );
+        else
+            getFileCRC( iv_it->second->HeaderFile().c_str(), checksum );
+			 	  
+        // END   -- Support for file checksum and comments
+	  
+        //START  -- Support for shortname tag
+        string fn;
+        string directory;
+        list<pair<string, string> > dirs;
+        
+        //select current filename to display if it is present, else select base filename
+        if ( strlen( iv_it->second->CompareFileName().c_str() ) > 0) 
+        {
+            fn = iv_it->second->CompareFileName().c_str();	
+            dirs = BBCFileUtils::extractFilenames(getCmdLineParm("currentdir"));
+        }
+        else
+        {
+            fn = iv_it->second->HeaderFile().c_str();
+            dirs = BBCFileUtils::extractFilenames(getCmdLineParm("baselinedir"));
+        }
+		
+        //select appropriate baseline/current dir from the list of baseline/current dirs
+        list<pair<string, string> >::iterator dirbegin = dirs.begin();
+        int p;
+        for(; dirbegin != dirs.end(); dirbegin++)
+        {
+            p = toLowerCaseWin(fn).find(toLowerCaseWin(dirbegin->first),0);
+            if(p!= string::npos)
+            {
+                directory = dirbegin->first;
+                break;
+            }
+        }
+                    
+        // remove baseline/current dir part of the filename        
+        string shortfilename;
+        shortfilename.reserve(256);    
+        shortfilename = removeBase(fn,directory);  
+        
+        // remove any leading directory separators from the filename 
+        shortfilename=trimLeadingDirSeparator(shortfilename);
+        shortfilename = toLowerCaseWin(shortfilename);  
+        
+        //create the shortname node
+        DOMElement* shortNameNode = createSimpleTextNode( NODE_ISSUELIST_HEADERFILE_SHORTNAME,shortfilename.c_str() );	 
+        //END  -- Support for shortname tag
+    
+		    vector<string> issueids;
+        for (; iv_it != iv->end(); ++iv_it)
+        {          
+            ReportIssue* issue = iv_it->second;
+            DOMElement* issuenode = createIssueNode(*issue);
+            headerfilenode->appendChild(issuenode);
+          
+            // START -- Support for file checksum and comments
+            string issueid;
+            char* text;
+            text = _X( issuenode->getElementsByTagName( _X( "typeid" ) )->item(0)->getTextContent() );
+            issueid = text;
+            _XX( text );
+          
+            text = _X( issuenode->getElementsByTagName( _X( "identityid" ) )->item(0)->getTextContent() );
+            issueid += text;
+            _XX( text );
+          
+            text = _X( issuenode->getElementsByTagName( _X( "cause" ) )->item(0)->getTextContent() );
+            issueid += text;
+            _XX( text );
+          
+            issueids.push_back( issueid );
+            // END   -- Support for file checksum and comments
+        }
+        
+        ret->appendChild(headerfilenode);
+        it++;
+        
+        // START -- Support for file checksum and comments
+        sort( issueids.begin(), issueids.end() );
+        getIssuesCRC( issueids, &checksum[7] );
+        DOMElement* checksumNode = createSimpleTextNode( NODE_ISSUELIST_HEADERFILE_CHECKSUM, checksum );
+        headerfilenode->appendChild( checksumNode );
+        // END   -- Support for file checksum and comments
+        
+        //START  -- Support for shortname tag
+        // insert the shortname node 
+        headerfilenode->appendChild( shortNameNode );
+        //END  -- Support for shortname tag
+    }
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createHeaderFileNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createHeaderFileNode()
+{
+    DOMElement* ret = NULL;
+    ret = createOpenNode(NODE_ISSUELIST_HEADERFILE);
+    return ret;
+}
+
+// START -- Support for file checksum and comments
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::getIssuesCRC
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::getIssuesCRC( const vector<string>& aIssueIdsVector, char* aCrcResult )
+{
+	unsigned long crc = 0xFFFFFFFFL;
+	vector<string>::const_iterator iter = aIssueIdsVector.begin();
+
+	for ( iter = aIssueIdsVector.begin(); iter != aIssueIdsVector.end(); iter++ )
+		for ( unsigned char* p = (unsigned char*) (*iter).c_str(); *p != '\0'; p++ )
+			crc = iCrcTable[ ( crc & 0xff ) ^ *p ] ^ ( crc >> 8 );
+	crc ^= 0xFFFFFFFFL;
+
+	// The checksum is base64-encoded into 6 characters before it is returned.
+	for ( int i = 0; i < 6; ++i )
+		aCrcResult[i] = KBase64[ ( crc >> ( 30 - 6 * i ) ) & 0x3f ];
+	aCrcResult[6] = '\0';
+
+	return;
+}
+// END   -- Support for file checksum and comments
+
+// START -- Support for file checksum and comments 
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::getFileCRC
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::getFileCRC( const char* aFilename, char* aCrcResult )
+{
+	unsigned long crc;
+	unsigned long previousCrc;
+	unsigned long length = 0;
+	unsigned char* buffer = new unsigned char[512];
+	unsigned char* p;
+	int count;
+	filebuf file;
+
+	// Calculate CRC for file; all sequences of whitespace and/or comments
+	// are replaced with _one_ space.
+	// States:
+	// 0 : "within star comment" : starts with "/*" and ends when
+	//                             the next "*/" is encountered
+	// 1 : "within line comment" : starts with "//" and ends when
+	//                             the next "/n" or "\r" is encountered
+	// 2 : "normal mode"         : "normal" text
+
+	if ( file.open( aFilename, ios::in ) == NULL )
+	{
+		strcpy( aCrcResult, "*************");
+		return;
+	}
+
+	crc = 0xFFFFFFFFL;
+	previousCrc = 0xFFFFFFFFL;
+	int state = 2;
+	char previousChar = ' ';
+	char slashPreviousChar = ' ';
+
+	for ( ; ; )
+	{
+		count = (int) file.sgetn( (char*) buffer, 512 );
+		if ( count == 0 )
+		{
+			break;
+		}
+
+		for ( p = buffer; count-- != 0; p++ )
+		{
+			if ( state == 0 )
+			{
+				if ( previousChar == '*' && *p == '/' )
+				{
+					state = 2;
+					previousChar = slashPreviousChar;
+					*p = ' ';
+				}
+			}
+			else if ( state == 1 )
+			{
+				if ( *p == '\r' || *p == '\n' )
+				{
+					state = 2;
+					previousChar = slashPreviousChar;
+					*p = ' ';
+				}
+			}
+
+			if ( state == 2 )
+			{
+				if ( *p == '/' && previousChar != '/' )
+				{
+					slashPreviousChar = previousChar;
+				}
+
+				if ( previousChar == '/' && *p == '*' )
+				{
+					state = 0;
+					crc = previousCrc;  // previous char should not be included in CRC
+					--length;
+					*p = ' '; // do not allow /*/ to be interpreted as a comment
+				}
+				else if ( previousChar == '/' && *p == '/' )
+				{
+					state = 1;
+					crc = previousCrc;  // previous char should not be included in CRC
+					--length;
+				}
+				else {
+					if ( *p == '\t' || *p == '\r' || *p == '\n' )
+					{
+						*p = ' ';
+					}
+					if ( *p != ' ' || previousChar != ' ' )
+					{
+						previousCrc = crc;
+						crc = iCrcTable[ ( crc & 0xff ) ^ *p ] ^ ( crc >> 8 );
+						++length;
+					}
+				}
+			}
+			previousChar = *p;
+		}
+	}
+	crc ^= 0xFFFFFFFFL;
+	file.close();
+	delete buffer;
+
+	// The 42-bit checksum is made up of
+	//  * bits 32-41   : length of file MOD 1024 (10 bits)
+	//  * bits 0-31    : the CRC-32 value
+	// This checksum is base64-encoded into 7 characters (42 bits / 6 bits) before it is returned.
+	int val;
+	length &= 0x3ff;
+
+	for ( int i = 0; i < 7; ++i )
+	{
+		if ( i == 0 )
+			val = length >> 4;
+		else if ( i == 1 )
+			val = ( ( length << 2 ) | ( crc >> 30 ) ) & 0x3f;
+		else
+			val = ( crc >> ( 30 - 6 * ( i - 1 ) ) ) & 0x3f;
+		aCrcResult[i] = KBase64[val];
+	}
+	aCrcResult[7] = '\0';
+
+	return;
+}
+// END   -- Support for file checksum and comments
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createTimestampNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createTimestampNode()
+{
+    DOMElement* ret = NULL;
+    int second, minute, hour, day, month, year;
+
+    time_t ttime;
+    time(&ttime);
+    struct tm* time = localtime(&ttime);
+    second = time->tm_sec;
+    minute = time->tm_min;
+    hour = time->tm_hour;
+    day = time->tm_mday;
+    month = time->tm_mon + 1;
+    year = time->tm_year + 1900;
+
+    ret = createOpenNode(NODE_HEADER_TIMESTAMP);
+    vector<DOMElement*> childvec;
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_DAY, day));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_MONTH, month));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_YEAR, year));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_HOUR, hour));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_MINUTE, minute));
+    childvec.push_back(createSimpleTextNode(NODE_HEADER_TIMESTAMP_SECOND, second));
+
+    appendChildrenToNode(ret, childvec);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::appendChildrenToNode
+// ----------------------------------------------------------------------------
+//
+void ReportGenerator::appendChildrenToNode(DOMElement* aParent, const vector<DOMElement*>& aChildren)
+{
+    size_t count = aChildren.size();
+    for (unsigned int i = 0; i < count; i++)
+    {
+        aParent->appendChild(aChildren.at(i));
+    }
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createSimpleTextNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createSimpleTextNode(const char* aNodeName, const char* aNodeText)
+{
+    DOMElement* ret = NULL;
+
+    XMLCh* ch = XMLString::transcode(aNodeName);
+    XMLCh* ch2 = XMLString::transcode(aNodeText);
+    ret = iDOMDocument->createElement(ch);
+    DOMText* tn = iDOMDocument->createTextNode(ch2);
+    ret->appendChild(tn);
+    XMLString::release(&ch);
+    XMLString::release(&ch2);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createSimpleTextNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createSimpleTextNode(const char* aNodeName, const XMLCh* aNodeText)
+{
+    DOMElement* ret = NULL;
+    XMLCh* ch = XMLString::transcode(aNodeName);
+    ret = iDOMDocument->createElement(ch);
+    DOMText* tn = iDOMDocument->createTextNode(aNodeText);
+    ret->appendChild(tn);
+    XMLString::release(&ch);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createSimpleTextNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createSimpleTextNode(const char* aNodeName, const int aInteger)
+{
+    DOMElement* ret = NULL;
+    XMLCh* ch = XMLString::transcode(aNodeName);
+    string temp;
+    itoa(aInteger, temp, 10);
+    XMLCh* ch2 = XMLString::transcode(temp.c_str());
+    ret = iDOMDocument->createElement(ch);
+    DOMText* tn = iDOMDocument->createTextNode(ch2);
+    ret->appendChild(tn);
+    XMLString::release(&ch);
+    XMLString::release(&ch2);
+    return ret;
+}
+// ----------------------------------------------------------------------------
+// ReportGenerator::createAttributeNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createAPIAttributeNode(const char* aNodeName, const char* aNodeAPI,const char* aNodeCategory)
+{
+    DOMElement* ret = NULL;
+
+    XMLCh* ch = XMLString::transcode(aNodeName);
+	XMLCh* apivalue = XMLString::transcode(aNodeAPI);
+    XMLCh* apiName = XMLString::transcode(NODE_ISSUELIST_HEADERFILE_ISSUE_APINAME);
+	XMLCh* apicategoryvalue = XMLString::transcode(aNodeCategory);
+	XMLCh* apicategoryname = XMLString::transcode(NODE_ISSUELIST_HEADERFILE_ISSUE_APICATEGORY);
+
+    ret = iDOMDocument->createElement(ch);
+	ret->setAttribute(apiName,apivalue);	
+	ret->setAttribute(apicategoryname,apicategoryvalue);
+	
+
+    XMLString::release(&ch);
+	XMLString::release(&apivalue);
+	XMLString::release(&apiName);
+	XMLString::release(&apicategoryvalue);
+    XMLString::release(&apicategoryname);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createCmdLineNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createCmdLineNode()
+{
+    DOMElement* ret = NULL;
+    ret = createOpenNode(NODE_HEADER_CMDLINE);
+    map<string, string>::iterator begin = iParams.begin();
+    while (begin != iParams.end())
+    {
+        DOMElement* ParamNode = createParmNode((*begin).first.c_str(),(*begin).second.c_str());
+        ret->appendChild(ParamNode);
+        begin++;
+    }
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createParmNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createParmNode(const char* aKey, const char* aValue)
+{
+    DOMElement* ret = NULL;
+    
+    // value <parm> **  </parm>
+    ret = createOpenNode(NODE_HEADER_CMDLINE_PARM);
+    
+    // <pname>
+    ret->appendChild(createSimpleTextNode(NODE_HEADER_CMDLINE_PARM_PNAME, aKey));
+    // <pvalue>
+    ret->appendChild(createSimpleTextNode(NODE_HEADER_CMDLINE_PARM_PVALUE, aValue));
+
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createDocumentationUrlString
+// ----------------------------------------------------------------------------
+//
+string ReportGenerator::createDocumentationUrlString(string element)
+{
+    string ret;
+    if (getCmdLineParm(DOCURL) != "Not speciefied") 
+    {
+        ret = getCmdLineParm(DOCURL) + element;
+    }
+    else
+    {
+        ret = "";
+    }
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createIssueNode
+// ----------------------------------------------------------------------------
+//
+DOMElement* ReportGenerator::createIssueNode(ReportIssue& aIssue)
+{
+    // IssueNode field element to report file
+    DOMElement* ret = NULL;
+
+    // create file name here
+    ret = createOpenNode(NODE_ISSUELIST_HEADERFILE_ISSUE);
+
+    vector<DOMElement*> childvec;
+    
+    // issue identifier field
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_ISSUEID, aIssue.Id()));
+
+    // issue type identifier field
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_TYPEID, aIssue.TypeId()));
+
+    // issue identify ( entity ) identifier field
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_IDENTITYID, aIssue.IdentityId()));
+
+    // identity description
+    childvec.push_back(createSimpleTextNode( NODE_ISSUELIST_HEADERFILE_ISSUE_IDENTITYDESCRIPTION, aIssue.IdentityDescription()));
+
+    // issue description field 
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_TYPESTRING, aIssue.TypeDescription()));
+    
+    // issue cause description a.k.a FQName
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_CAUSE, aIssue.FQName().c_str()));
+    
+    // issue documentation finder field
+	childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_DOCUMENTATION, createDocumentationUrlString(aIssue.FQName()).c_str()));
+   
+    // issue ignore finder field
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_IGNOREINFORMATION, aIssue.IgnoreInformationDescription().c_str()));
+    
+    // issue linenumber field
+    childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_LINENUMBER, aIssue.LineNumber()));
+    
+    // issue extrainformation field
+    //childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_EXTRAINFORMATION, aIssue.ExtraInformationDescription().c_str()));
+    
+    // binary compatibility severity sub field for issue
+    DOMElement* bcseverity = createOpenNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY);
+    bcseverity->appendChild(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY_TYPEID, aIssue.BCSeverity()));
+    bcseverity->appendChild(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY_TYPESTRING, aIssue.BCSeverityDescription()));
+
+    // source compatibility severity sub field for issue
+	DOMElement* scseverity = createOpenNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SCSEVERITY);
+    scseverity->appendChild(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY_TYPEID, aIssue.SCSeverity()));
+    scseverity->appendChild(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY_TYPESTRING, aIssue.SCSeverityDescription()));
+	
+	// if iisue type is compilation error,  description of compilation error
+	if(aIssue.TypeId() == EIssueTypeCompilationError)
+		childvec.push_back(createSimpleTextNode(NODE_ISSUELIST_HEADERFILE_ISSUE_COMPILATION_ERROR, aIssue.CompilationError().c_str()));
+
+
+    appendChildrenToNode(ret, childvec);
+    ret->appendChild(bcseverity);
+	ret->appendChild(scseverity);
+    return ret;
+}
+
+// ----------------------------------------------------------------------------
+// ReportGenerator::createSeverityNode
+// ----------------------------------------------------------------------------
+//
+//DOMElement* ReportGenerator::createSeverityNode(const int aId)
+DOMElement* ReportGenerator::createSeverityNode()
+{
+    DOMElement* ret = NULL;
+    ret = createOpenNode(NODE_ISSUELIST_HEADERFILE_ISSUE_SEVERITY);
+    return ret;
+}
+