diff -r 000000000000 -r 638b9c697799 apicompatanamdw/compatanalysercmd/headeranalyser/src/XMLUtils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/apicompatanamdw/compatanalysercmd/headeranalyser/src/XMLUtils.cpp Tue Jan 12 14:52:39 2010 +0530 @@ -0,0 +1,2457 @@ +/* +* 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 +#include +#include +#include + +#include +#include +#include "XMLUtils.h" +#include "XMLStringConst.h" +#include "NodeIndex.h" +#include "XMLModuleErrorHandler.h" +#include "BBCFileUtils.h" +#include "HAException.h" +#include "Utils.h" + +using namespace std; + +XERCES_CPP_NAMESPACE_USE + +//Attributes of the elements, copied from the unofficial DTD for GCCXML + + +// +// +// +// +//Base +// +const int KBaseAttributeCount = 3; +const EntityAttributeElement KBaseAttributes[KBaseAttributeCount]={ + {KXMLTypeString,EIdAttribute}, + {KXMLAccessString,ESimpleAttribute}, + {KXMLVirtualString,EBooleanAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KVariableAttributeCount = 4; +const EntityAttributeElement KVariableAttributes[KVariableAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLTypeString,EIdAttribute}, + {KXMLInitString,EOptionalSimpleAttribute}, + //{KXMLContextString,EIdAttribute}, + {KXMLAccessString,EOptionalSimpleAttribute} + }; + +// +// +// +// +// +// +// +const int KFundamentalTypeAttributeCount = 3; +const EntityAttributeElement KFundamentalTypeAttributes[KFundamentalTypeAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLSizeString,ESimpleAttribute}, + {KXMLAlignString,ESimpleAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +const int KTypedefAttributeCount = 2; +const EntityAttributeElement KTypedefAttributes[KTypedefAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLTypeString,EIdAttribute}//, + //{KXMLContextString,EIdAttribute} + }; + +// +// +// +// +// +// +// +// +const int KNamespaceAttributeCount = 2; +const EntityAttributeElement KNamespaceAttributes[KNamespaceAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLContextString,EOptionalIdAttribute}//, + //{KXMLMembersString,EIdAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +const int KCvQualifiedTypeAttributeCount = 2; +const EntityAttributeElement KCvQualifiedTypeAttributes[KCvQualifiedTypeAttributeCount]={ + {KXMLTypeString,EIdAttribute}, + {KXMLConstString,EBooleanAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KFunctionAttributeCount = 4; +const EntityAttributeElement KFunctionAttributes[KFunctionAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLReturnsString,EIdAttribute}, + {KXMLContextString,EIdAttribute}, + {KXMLConstString,EBooleanAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KEnumerationAttributeCount = 4; +const EntityAttributeElement KEnumerationAttributes[KEnumerationAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLAlignString,ESimpleAttribute}, + //{KXMLContextString,EIdAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLSizeString,ESimpleAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KFieldAttributeCount = 5; +const EntityAttributeElement KFieldAttributes[KFieldAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLMutableString,EBooleanAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLOffsetString,ESimpleAttribute}, + {KXMLTypeString,ETypeAttribute} + }; + +// +// +// +// +// +// +// +const int KArgumentAttributeCount = 3; +const EntityAttributeElement KArgumentAttributes[KArgumentAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLTypeString,EIdAttribute}, + {KXMLDefaultString,EOptionalSimpleAttribute} + }; +// +const int KEllipsisAttributeCount = 0; +//const EntityAttributeElement KEllipsisAttributes[KEllipsisAttributeCount]={}; + + +// +// +// +// +// +// +// +// +const int KArrayTypeAttributeCount = 2; +const EntityAttributeElement KArrayTypeAttributes[KArrayTypeAttributeCount]={ + {KXMLTypeString,EIdAttribute}, + {KXMLMaxString,ESimpleAttribute} + }; +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KClassAttributeCount = 6; +const EntityAttributeElement KClassAttributes[KClassAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLAlignString,ESimpleAttribute}, + {KXMIncompleteString,EBooleanAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLSizeString,ESimpleAttribute}, + {KXMLMebmersString,EIdAttribute} + }; +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KConstructorAttributeCount = 2; +const EntityAttributeElement KConstructorAttributes[KConstructorAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLNameString,ESimpleAttribute} + }; +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KConverterAttributeCount = 0; +//const EntityAttributeElement KConverterAttributes[KConverterAttributeCount]={}; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KDestructorAttributeCount = 3; +const EntityAttributeElement KDestructorAttributes[KDestructorAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLVirtualString,EBooleanAttribute} + }; +// +// +// +const int KEnumValueAttributeCount = 2; +const EntityAttributeElement KEnumValueAttributes[KEnumValueAttributeCount]={ + {KXMLInitString,ESimpleAttribute}, + {KXMLNameString,ESimpleAttribute} + }; +// +const int KFileAttributeCount = 0; +//const EntityAttributeElement KFileAttributes[KFileAttributeCount]={}; + +// +// +// +// +const int KFunctionTypeAttributeCount = 1; +const EntityAttributeElement KFunctionTypeAttributes[KFunctionTypeAttributeCount]={ + {KXMLReturnsString,EIdAttribute} + }; +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KMethodAttributeCount = 7; +const EntityAttributeElement KMethodAttributes[KMethodAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLConstString,EBooleanAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLPureVirtualString,EBooleanAttribute}, + {KXMLReturnsString,EIdAttribute}, + {KXMLStaticString,EBooleanAttribute}, + {KXMLVirtualString,EBooleanAttribute} + }; + +// +// +// +// +// +const int KMethodTypeAttributeCount = 2; +const EntityAttributeElement KMethodTypeAttributes[KMethodTypeAttributeCount]={ + {KXMLBaseTypeString,EIdAttribute}, + {KXMLReturnsString,EIdAttribute}, + }; +// +// +// +// +// +// +const int KNamespaceAliasAttributeCount = 0; +//const EntityAttributeElement KNamespaceAliasAttributes[KNamespaceAliasAttributeCount]={}; + +// +// +// +// +// +// +// +const int KOffsetTypeAttributeCount = 0; +//const EntityAttributeElement KOffsetTypeAttributes[KOffsetTypeAttributeCount]={}; + +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KOperatorFunctionAttributeCount = 2; +const EntityAttributeElement KOperatorFunctionAttributes[KOperatorFunctionAttributeCount]={ + {KXMLNameString,ESimpleAttribute}, + {KXMLReturnsString,EIdAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KOperatorMethodAttributeCount = 6; +const EntityAttributeElement KOperatorMethodAttributes[KOperatorMethodAttributeCount]={ + {KXMLAccessString,EOptionalSimpleAttribute}, + {KXMLConstString,EBooleanAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLPureVirtualString,EBooleanAttribute}, + {KXMLVirtualString,EBooleanAttribute}, + {KXMLReturnsString,EIdAttribute} + }; +// +// +// +// +// +// +const int KPointerTypeAttributeCount = 1; +const EntityAttributeElement KPointerTypeAttributes[KPointerTypeAttributeCount]={ + {KXMLTypeString,EIdAttribute} + }; +// +// +// +// +// +// +const int KReferenceTypeAttributeCount = 1; +const EntityAttributeElement KReferenceTypeAttributes[KReferenceTypeAttributeCount]={ + {KXMLTypeString,EIdAttribute} + }; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KStructAttributeCount = 6; +const EntityAttributeElement KStructAttributes[KStructAttributeCount]={ + {KXMLAccessString,ESimpleAttribute}, + {KXMLAbstractString,EBooleanAttribute}, + {KXMLBasesString,EIdAttribute}, + {KXMLNameString,ESimpleAttribute}, + {KXMLSizeString,ESimpleAttribute}, + {KXMLMembersString,EIdAttribute} + }; + +// +// +// +// +// +// +const int KUnimplementedAttributeCount = 0; +//const EntityAttributeElement KUnimplementedAttributes[KUnimplementedAttributeCount]={}; + +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +// +const int KUnionAttributeCount = 5; +const EntityAttributeElement KUnionAttributes[KUnionAttributeCount]={ + {KXMLAccessString,ESimpleAttribute}, + {KXMLAlignString,ESimpleAttribute}, + {KXMLBasesString,EOptionalIdAttribute}, + {KXMLMembersString,EIdAttribute}, + {KXMLSizeString,ESimpleAttribute} + }; + +const EntityComparisonElement KEntityComparisonTable[KEntityComparisonTableCount]= + { + {KXMLBaseString,KBaseAttributes,KBaseAttributeCount}, + {KXMLFundamentalTypeString,KFundamentalTypeAttributes,KFundamentalTypeAttributeCount}, + {KXMLTypedefString,KTypedefAttributes,KTypedefAttributeCount}, + {KXMLNamespaceString,KNamespaceAttributes,KNamespaceAttributeCount}, + {KXMLCvQualifiedTypeString,KCvQualifiedTypeAttributes,KCvQualifiedTypeAttributeCount}, + {KXMLVariableString,KVariableAttributes,KVariableAttributeCount}, + {KXMLFundamentalTypeString,KFundamentalTypeAttributes,KFundamentalTypeAttributeCount}, + {KXMLTypedefString,KTypedefAttributes,KTypedefAttributeCount}, + {KXMLNamespaceString,KNamespaceAttributes,KNamespaceAttributeCount}, + {KXMLFunctionString,KFunctionAttributes,KFunctionAttributeCount}, + {KXMLEnumerationString,KEnumerationAttributes,KEnumerationAttributeCount}, + {KXMLFieldString,KFieldAttributes,KFieldAttributeCount}, + {KXMLArgumentString,KArgumentAttributes,KArgumentAttributeCount}, + {KXMLEllipsisString,NULL,KEllipsisAttributeCount}, + {KXMLArrayTypeString,KArrayTypeAttributes,KArrayTypeAttributeCount}, + {KXMLClassString,KClassAttributes,KClassAttributeCount}, + {KXMLConstructorString,KConstructorAttributes,KConstructorAttributeCount}, + {KXMLConverterString,NULL,KConverterAttributeCount}, + {KXMLDestructorString,KDestructorAttributes,KDestructorAttributeCount}, + {KXMLEnumValueString,KEnumValueAttributes,KEnumValueAttributeCount}, + {KXMLFileString,NULL,KFileAttributeCount}, + {KXMLFunctionTypeString,KFunctionTypeAttributes,KFunctionTypeAttributeCount}, + {KXMLMethodString,KMethodAttributes,KMethodAttributeCount}, + {KXMLMethodTypeString,KMethodTypeAttributes,KMethodTypeAttributeCount}, + {KXMLNamespaceAliasString,NULL,KNamespaceAliasAttributeCount}, + {KXMLOffsetTypeString,NULL,KOffsetTypeAttributeCount}, + {KXMLOperatorFunctionString,KOperatorFunctionAttributes,KOperatorFunctionAttributeCount}, + {KXMLOperatorMethodString,KOperatorMethodAttributes,KOperatorMethodAttributeCount}, + {KXMLPointerTypeString,KPointerTypeAttributes,KPointerTypeAttributeCount}, + {KXMLReferenceTypeString,KReferenceTypeAttributes,KReferenceTypeAttributeCount}, + {KXMLStructString,KStructAttributes,KStructAttributeCount}, + {KXMLUnimplementedString,NULL,KUnimplementedAttributeCount}, + {KXMLUnionString,KUnionAttributes,KUnionAttributeCount} + }; + + + +// ---------------------------------------------------------------------------- +// IsProperNode +// ---------------------------------------------------------------------------- +// +bool IsProperNode(HANodeIterator node) +{ + bool ret = (DOMNode::ELEMENT_NODE == node->getNodeType()); + + if (ret) + { + const XMLCh * nodecontext = node.GetAttribute(KXMLContextString); + if (nodecontext) + { + ret = !Equals(nodecontext,KXMLIgnoreContext); + } + } + + if (ret) + { + if ( node.CheckForBooleanAttribute(KXMLArtificialString) ) + { + const XMLCh * nodetype = node->getNodeName(); + + ret = Equals(nodetype,KXMLUnionString) || + Equals(nodetype,KXMLStructString) || + Equals(nodetype,KXMLEnumerationString) || + Equals(nodetype,KXMLClassString); + } + } + + return ret; + +} + +// ---------------------------------------------------------------------------- +// IsNamedNode +// ---------------------------------------------------------------------------- +// +bool IsNamedNode(HANodeIterator node) + { + bool ret = (DOMNode::ELEMENT_NODE == node->getNodeType()); + + if (ret) + { + + const XMLCh* name = node.GetAttribute(KXMLNameString); + + if (!name) + { + return false; + } + + const XMLCh * nodetype = node->getNodeName(); + assert(nodetype != NULL); + + if ( !(Equals(nodetype,KXMLClassString ) || + Equals(nodetype,KXMLEnumerationString ) || + Equals(nodetype,KXMLFunctionString ) || + Equals(nodetype,KXMLNamespaceString ) || + Equals(nodetype,KXMLOperatorFunctionString ) || + Equals(nodetype,KXMLStructString ) || + Equals(nodetype,KXMLTypedefString ) || + Equals(nodetype,KXMLUnionString ) || + Equals(nodetype,KXMLVariableString )) ) + { + ret = false; + } + + } + + return ret; +} + +// ---------------------------------------------------------------------------- +// IsFunction +// ---------------------------------------------------------------------------- +// +void printXMLCh(const XMLCh* s1) +{ + char * tmp = XMLString::transcode(s1); + + cout << tmp; + + XMLString::release(&tmp); +} + +// ---------------------------------------------------------------------------- +// toString +// ---------------------------------------------------------------------------- +// +string toString(const XMLCh* s1) +{ + char* ts1 = XMLString::transcode(s1); + string value; + if(ts1 != NULL) + { + value = ts1; + XMLString::release(&ts1); + } + return value; +} + +// ---------------------------------------------------------------------------- +// Equals +// ---------------------------------------------------------------------------- +// +bool Equals(const XMLCh* s1, const XMLCh* s2) +{ + return XMLString::equals(s1,s2); +} + + +// ---------------------------------------------------------------------------- +// Equals +// ---------------------------------------------------------------------------- +// +bool Equals(const char* s1, const char* s2) +{ + return XMLString::equals(s1,s2); +} + +// ---------------------------------------------------------------------------- +// Equals +// ---------------------------------------------------------------------------- +// +bool Equals(const XMLCh* s1, const char* s2) +{ + XMLCh* ts2 = XMLString::transcode(s2); + bool ret = XMLString::equals(s1,ts2); + XMLString::release(&ts2); + return ret; +} + +// ---------------------------------------------------------------------------- +// StartsWith +// ---------------------------------------------------------------------------- +// +bool StartsWith(const XMLCh* s1, const char* s2) +{ + XMLCh* ts2 = XMLString::transcode(s2); + bool ret = XMLString::startsWith(s1,ts2); + XMLString::release(&ts2); + return ret; +} + +// ---------------------------------------------------------------------------- +// StartsWith +// ---------------------------------------------------------------------------- +// +bool StartsWith(const XMLCh* s1, const XMLCh* s2) +{ + bool ret = XMLString::startsWith(s1,s2); + return ret; +} + +// ---------------------------------------------------------------------------- +// Equals +// ---------------------------------------------------------------------------- +// +bool Equals(const char* s2, const XMLCh* s1) +{ + return Equals(s1,s2); +} + + +// ---------------------------------------------------------------------------- +// SetAttribute +// ---------------------------------------------------------------------------- +// +void SetAttribute(DOMNode * node, const XMLCh* attribute, const XMLCh* value) +{ + short nodetype = node->getNodeType(); + assert(nodetype == DOMNode::ELEMENT_NODE); + + DOMElement * element = static_cast(node); + + element->setAttribute(attribute,value); +} + +// ---------------------------------------------------------------------------- +// SetAttribute +// ---------------------------------------------------------------------------- +// +void SetAttribute(DOMNode * node, const char* attribute, const char* value) +{ + XMLCh* tattribute = XMLString::transcode(attribute); + XMLCh* tvalue = XMLString::transcode(value); + SetAttribute(node,tattribute,tvalue); + XMLString::release(&tattribute); + XMLString::release(&tvalue); +} + +// ---------------------------------------------------------------------------- +// GetAttribute +// ---------------------------------------------------------------------------- +// +const XMLCh* GetAttribute(DOMNode * node, const XMLCh* attribute) +{ + DOMNamedNodeMap * attributes = node->getAttributes(); + + if ( !attributes ) + { + return NULL; + } + + DOMNode * attributeId = attributes->getNamedItem(attribute); + + if ( attributeId ) + { + return attributeId->getNodeValue(); + } + + return NULL; +} + +// ---------------------------------------------------------------------------- +// GetAttribute +// ---------------------------------------------------------------------------- +// +const XMLCh* GetAttribute(DOMNode * node, const char * attribute) +{ + XMLCh * idident = XMLString::transcode(attribute); + const XMLCh * attributeValue = GetAttribute(node,idident); + XMLString::release(&idident); + + return attributeValue; + +} + +// ---------------------------------------------------------------------------- +// CheckForBooleanAttribute +// ---------------------------------------------------------------------------- +// +bool CheckForBooleanAttribute(DOMNode * node, const XMLCh* attribute) +{ + const XMLCh* attributeValue = GetAttribute(node, attribute); + + if ( attributeValue ) + { + return Equals(attributeValue,"1"); + } + return false; +} + +// ---------------------------------------------------------------------------- +// CheckForBooleanAttribute +// ---------------------------------------------------------------------------- +// +bool CheckForBooleanAttribute(DOMNode * node, const char* attribute) +{ + const XMLCh* attributeValue = GetAttribute(node, attribute); + + if ( attributeValue ) + { + return Equals(attributeValue,"1"); + } + return false; +} + +// ---------------------------------------------------------------------------- +// GetSize +// ---------------------------------------------------------------------------- +// +const XMLCh* GetSize(HANodeIterator node) +{ + const XMLCh* size = node.GetAttribute(KXMLSizeString); + + if ( !size ) + { + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + assert(type); + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + + return GetSize(typenode); + } + + return size; +} + +// ---------------------------------------------------------------------------- +// GetTypeName +// ---------------------------------------------------------------------------- +// +string GetTypeName(HANodeIterator node) +{ + const XMLCh* fqname = node.GetAttribute(KXMLBBCFQNameString); + + if (fqname) + { + return toString(fqname); + } + + string ret; + + const XMLCh * nodename = node->getNodeName(); + + if ( Equals(nodename,KXMLEllipsisString) ) + { + ret += " "; + ret += "..."; + ret += ","; + } + else if ( Equals(nodename, KXMLFunctionTypeString) ) + { + //ret += "(*)"; + const XMLCh* retType = node.GetAttribute(KXMLReturnsString); + if( retType ) + { + HANodeIterator typenode(node); + bool typefound = typenode.FindNodeById(retType); + assert(typefound); + ret += GetTypeName(typenode) + " "; + } + + ret += "(*) "; + ret += GenerateFunctionSignature(node); + } + else if ( Equals(nodename, KXMLFundamentalTypeString) ) + { + ret += GenerateFullyQualifiedName(node); + } + else if ( Equals(nodename, KXMLTypedefString) ) + { + ret += GenerateFullyQualifiedName(node); + } + else if ( Equals(nodename,KXMLCvQualifiedTypeString) ) + { + + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + assert(type); + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + + if ( node.CheckForBooleanAttribute(KXMLConstString) ) + { + ret += " const "; + } + ret += GetTypeName(typenode); + } + else if ( Equals(nodename,KXMLArrayTypeString) ) + { + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + assert(type); + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + ret += GetTypeName(typenode); + ret += "[]"; + } + else if ( Equals(nodename,KXMLPointerTypeString) ) + { + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + assert(type); + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + ret += GetTypeName(typenode); + if(!Equals(typenode->getNodeName(), KXMLFunctionTypeString) ) + { + ret += "*"; + } + } + else if ( Equals(nodename,KXMLReferenceTypeString) ) + { + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + assert(type); + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + ret += GetTypeName(typenode); + ret += "&"; + } + else + { + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + //assert(type); + if ( type ) + { + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + ret += GetTypeName(typenode); + }else + { + ret += GenerateFullyQualifiedName(node); + } + } + + XMLCh* fqnamep = XMLString::transcode(ret.c_str()); + node.SetAttribute(KXMLBBCFQNameString, fqnamep); + XMLString::release(&fqnamep); + + return ret; +} + +const XMLCh* FindAttributeValueForType(const HANodeIterator& node, const char* attribute) +{ + XMLCh* ch_attribute = XMLString::transcode(attribute); + const XMLCh* ret = FindAttributeValueForType(node,ch_attribute); + XMLString::release(&ch_attribute); + return ret; + +} + +// ---------------------------------------------------------------------------- +// FindAttributeValueForType +// ---------------------------------------------------------------------------- +// +const XMLCh* FindAttributeValueForType(const HANodeIterator& node, const XMLCh* attribute) +{ + const XMLCh* size = node.GetAttribute(attribute); + + if (size) + { + return size; + } + + const XMLCh* type = node.GetAttribute(KXMLTypeString); + + if ( !type ) + { + return NULL; + } + + HANodeIterator typenode(node); + + bool typefound = typenode.FindNodeById(type); + + assert(typefound); + + return FindAttributeValueForType(typenode,attribute); +} + +// ---------------------------------------------------------------------------- +// IsFunction +// ---------------------------------------------------------------------------- +// +bool IsFunction(HANodeIterator node) + { + //Add the return value and parameters to the name (due to overloading) + const XMLCh* name = node.current->getNodeName(); + + if (!name) + { + return false; + } + + if ( Equals(name,KXMLConstructorString) || + Equals(name,KXMLMethodString) || + Equals(name,KXMLFunctionString) || + Equals(name,KXMLOperatorFunctionString) || + Equals(name,KXMLOperatorMethodString) || + Equals(name,KXMLDestructorString) || + Equals(name,KXMLFunctionTypeString) + ) + { + return true; + } + + return false; + } + +void GetElementNodes( HANodeIterator node, + DOMNodeList* domNodes, + std::vector& elemNodes) +{ + XMLSize_t domNodeCount = domNodes->getLength(); + for(unsigned int i = 0; i < domNodeCount; ++i) + { + DOMNode* domNode = domNodes->item(i); + HANodeIterator nodeit(node); + nodeit.current = domNode; + + short nodetype = nodeit->getNodeType(); + if (nodetype == DOMNode::ELEMENT_NODE) + { + elemNodes.push_back(domNodes->item(i)); + } + } +} + +// ---------------------------------------------------------------------------- +// GenerateFunctionSignature +// Builds function signature which contains function name and all the parameters. +// ---------------------------------------------------------------------------- +// +string GenerateFunctionSignature(HANodeIterator node) +{ + short nodetype = node->getNodeType(); + assert(nodetype == DOMNode::ELEMENT_NODE); + assert(IsFunction(node)); + + string ret; + + const XMLCh * name = node->getNodeName(); + + if ( Equals(name, KXMLDestructorString) ) + { + ret += "~"; + } + else if ( Equals(name,KXMLOperatorMethodString) || Equals(name,KXMLOperatorFunctionString) ) + { + ret += "operator"; + } + + const XMLCh* nameatt = node.GetAttribute(KXMLNameString); + + if (nameatt) + { + ret += toString(nameatt); + } + + ret +="("; + + DOMElement * nodeelement = static_cast(node.current); + DOMNodeList* childs = nodeelement->getChildNodes(); + XMLSize_t childcount = childs->getLength(); + + unsigned int i = 0; + for (i = 0; i < childcount; ++i) + { + DOMNode* child = childs->item(i); + HANodeIterator childit(node); + childit.current = child; + + short nodetype = childit->getNodeType(); + if (nodetype == DOMNode::ELEMENT_NODE) + { + ret += " " + GetTypeName(childit) + ","; + } + + } + + if (ret[ret.length()-1] == ',') + { + ret.resize(ret.length()-1); + } + ret += " )"; + + if ( node.CheckForBooleanAttribute(KXMLConstString) ) + { + ret += " const"; + } + + return ret; +} + +// ---------------------------------------------------------------------------- +// GenerateFullyQualifiedName +// ---------------------------------------------------------------------------- +// +string GenerateFullyQualifiedName(HANodeIterator node) +{ + const XMLCh* fqname = node.GetAttribute(KXMLBBCFQNameString); + + if (fqname) + { + return toString(fqname); + } + + string name; + + const XMLCh* nameatt = 0; + const XMLCh* mangledatt = 0; + + if( IsAnonymousType(node) ) + { + // Node is of "anonymous" type so it has not name. + // Let's use the gccxml generated id instead. + nameatt = node.GetAttribute(KXMLIdString); + } + else + { + nameatt = node.GetAttribute(KXMLNameString); + } + + if ( nameatt ) + { + if ( Equals(KXMLNamespaceString,node->getNodeName()) ) + { + if ( StartsWith(nameatt,KXMLAnonymousNamespacePrefix) ) + { + name += ""; + } + else if ( Equals(KXMLGlobalNamespaceString,nameatt) ) + { + //Skip the global namespace + + }else + { + name += toString(nameatt); + } + + } + else if ( IsFunction(node) ) + { + //Add the return value and parameters to the name (due to overloading) + // Consider mangled attribute here. + mangledatt = node.GetAttribute(KXMLMangledString); + string mangled = toString(mangledatt); + name += GenerateFunctionSignature(node) + __FUN_MANGLED__ + toString(mangledatt); + + } + else + { + name += toString(nameatt); + } + } + + const XMLCh* contextatt = node.GetAttribute(KXMLContextString); + + if ( contextatt ) + { + HANodeIterator basenode(node); + basenode.FindNodeById(contextatt); + string basename = GenerateFullyQualifiedName(basenode); + name = basename + "::" + name; + } + + + if ( nameatt || contextatt) + { + XMLCh* fqnamep = XMLString::transcode(name.c_str()); + node.SetAttribute(KXMLBBCFQNameString, fqnamep); + XMLString::release(&fqnamep); + } + + return name; +} + +// ---------------------------------------------------------------------------- +// FindComparison +// ---------------------------------------------------------------------------- +// +const EntityComparisonElement* FindComparison(const XMLCh* nodeName) +{ + int i = 0; + for (i = 0;i < KEntityComparisonTableCount; ++i) + { + if ( Equals(KEntityComparisonTable[i].iEntityName,nodeName) ) + { + return &KEntityComparisonTable[i]; + } + } + return NULL; + +} + +// ---------------------------------------------------------------------------- +// CompareIdLists +// ---------------------------------------------------------------------------- +// +bool CompareIdLists(HANodeIterator baseline, HANodeIterator current,const XMLCh* idAttributeName) +{ + HANodeIterator newbaseline = baseline; + const XMLCh* baselineids = baseline.GetAttribute(idAttributeName); + + HANodeIterator newcurrent = current; + const XMLCh* currentids = current.GetAttribute(idAttributeName); + + BaseRefVectorOf< XMLCh > * baselineidtokens_ptr = XMLString::tokenizeString (baselineids); + BaseRefVectorOf< XMLCh > * currentidtokens_ptr = XMLString::tokenizeString (currentids); + + auto_ptr > baselineidtokens(baselineidtokens_ptr); + auto_ptr > currentidtokens(currentidtokens_ptr); + + for (unsigned int i = 0; i < baselineidtokens->size(); ++i) + { + const XMLCh * baselineid = baselineidtokens->elementAt(i); + const XMLCh * currentid = currentidtokens->elementAt(i); + newbaseline.FindNodeById(baselineid); + newcurrent.FindNodeById(currentid); + + if ( !CompareNodes(newbaseline,newcurrent) ) + { + + return false; + } + } + + + return true; +} + +// ---------------------------------------------------------------------------- +// CompareNodes +// ---------------------------------------------------------------------------- +// +bool CompareNodes(HANodeIterator baseline, HANodeIterator current ) +{ + assert(Equals(baseline->getNodeName(),current->getNodeName())); + + const EntityComparisonElement* compElem = FindComparison(baseline->getNodeName()); + + assert(compElem); + + int i = 0; + for (i = 0;i < compElem->iAttributeCount; ++i) + { + const EntityAttributeElement* attributes = &compElem->iAttributeList[i]; + + if ( !CompareAttributes(baseline, current, attributes->iAttributeName, attributes->iAttributeType) ) + { + return false; + } + } + return true; +} + +// ---------------------------------------------------------------------------- +// CompareFileNames +// ---------------------------------------------------------------------------- +// +bool CompareFileNames(string first,string second) +{ + if (first.length() != second.length() ) + { + return false; + } + + unsigned int i = 0; + for (i = 0; i < first.length(); ++i) + { + if (first.at(i) == '\\' || first.at(i) == '/' ) + { + if (second.at(i) != '\\' && second.at(i) != '/' ) + { + return false; + } + } else + { + if ( tolower(first.at(i)) != tolower(second.at(i)) ) + { + return false; + } + } + + } + return true; +} + +// ---------------------------------------------------------------------------- +// CompareAttributes +// ---------------------------------------------------------------------------- +// +bool CompareAttributes(HANodeIterator baseline, HANodeIterator current, const char* attributeName, TAttributeType attributeType) +{ + XMLCh* attributeName2 = XMLString::transcode(attributeName); + bool ret = CompareAttributes(baseline,current,attributeName2,attributeType); + XMLString::release(&attributeName2); + return ret; + +} + +// ---------------------------------------------------------------------------- +// CompareAttributes +// ---------------------------------------------------------------------------- +// +bool CompareAttributes(HANodeIterator baseline, HANodeIterator current, const XMLCh* attributeName, TAttributeType attributeType) +{ + switch (attributeType) + { + case EOptionalTypeAttribute: + { + if ( NULL == baseline.GetAttribute(attributeName) || + NULL == current.GetAttribute(attributeName) ) + { + if ( baseline.GetAttribute(attributeName) || + current.GetAttribute(attributeName) ) + { + return false; + } + else + { + return true; + } + break; + } + } + case ETypeAttribute: + { + const XMLCh * baselineid = baseline.GetAttribute(attributeName); + const XMLCh * currentid = current.GetAttribute(attributeName); + assert(baselineid); + assert(baselineid); + HANodeIterator newbaseline(baseline); + HANodeIterator newcurrent(current); + bool ret1=newbaseline.FindNodeById(baselineid); + bool ret2=newcurrent.FindNodeById(currentid); + assert(ret1 && ret2); + string baselinetype = GetTypeName(newbaseline); + string currenttype = GetTypeName(newcurrent); + + // Test if either of the types is incomplete. + // If either one is incomplete, the size and alignment + // does not match. We don't check the size and alignment + // for incomplete types, since the actual types are + // checked with their headers. + bool bincomplete = newbaseline.CheckForBooleanAttribute(KXMIncompleteString); + bool cincomplete = newcurrent.CheckForBooleanAttribute(KXMIncompleteString); + + if( !bincomplete && !cincomplete ) + { + const XMLCh * baselinesize = FindAttributeValueForType(newbaseline,KXMLSizeString); + const XMLCh * currentsize = FindAttributeValueForType(newcurrent,KXMLSizeString); + + const XMLCh * baselinealign = FindAttributeValueForType(newbaseline,KXMLAlignString); + const XMLCh * currentalign = FindAttributeValueForType(newcurrent,KXMLAlignString); + + if ( !baselinesize ) + { + baselinesize = baselinealign; + } + + if ( !currentsize ) + { + currentsize = currentalign; + } + + return baselinetype == currenttype && Equals(baselinesize,currentsize) && Equals(baselinealign, currentalign); + } + else + { + // either or both of the types were incomplete, so compare just the type names. + return baselinetype == currenttype; + } + } + + case EOptionalSimpleAttribute: + { + if ( NULL == baseline.GetAttribute(attributeName) || + NULL == current.GetAttribute(attributeName) ) + { + if ( baseline.GetAttribute(attributeName) || + current.GetAttribute(attributeName) ) + { + return false; + } + else + { + return true; + } + break; + } + } + case ESimpleAttribute: + case EBooleanAttribute: + { + if (!Equals( + baseline.GetAttribute(attributeName), + current.GetAttribute(attributeName) + ) + ) + { + return false; + } + break; + } + + case EOptionalIdAttribute: + { + if ( NULL == baseline.GetAttribute(attributeName) || + NULL == current.GetAttribute(attributeName)) + { + if ( baseline.GetAttribute(attributeName) || + current.GetAttribute(attributeName) ) + { + return false; + } + else + { + return true; + } + break; + } + } + case EIdAttribute: + { + if (!CompareIdLists(baseline, current, attributeName)) + { + return false; + } + break; + } + + default: + { + //Attribute type unknown + assert(false); + } + } + return true; +} + +// ---------------------------------------------------------------------------- +// CalcDerivedAccessModifier +// ---------------------------------------------------------------------------- +// +#if 0 +TAccess CalcDerivedAccessModifier(TAccess member, TAccess inheritance) +{ + TAccess ret=EAccessGlobal; + switch (inheritance) + { + case EAccessGlobal: + case EAccessPublic: + switch(member) + { + case EAccessGlobal: + ret = member; + break; + case EAccessPublic: + ret = member; + break; + case EAccessProtected: + ret = member; + break; + case EAccessPrivate: + ret = EAccessHidden; + break; + case EAccessHidden: + ret = member; + break; + default: + assert(false); + break; + } + break; + case EAccessProtected: + switch(member) + { + case EAccessGlobal: + ret = member; + break; + case EAccessPublic: + ret = EAccessProtected; + break; + case EAccessProtected: + ret = EAccessProtected; + break; + case EAccessPrivate: + ret = EAccessHidden; + break; + case EAccessHidden: + ret = member; + break; + default: + assert(false); + break; + } + break; + case EAccessPrivate: + switch(member) + { + case EAccessGlobal: + ret = member; + break; + case EAccessPublic: + ret = EAccessHidden; + break; + case EAccessProtected: + ret = EAccessHidden; + break; + case EAccessPrivate: + ret = EAccessHidden; + break; + case EAccessHidden: + ret = EAccessHidden; + break; + default: + assert(false); + break; + } + break; + default: + assert(false); + break; + } + return ret; +} +#endif + +// ---------------------------------------------------------------------------- +// CalcAccessModifier +// ---------------------------------------------------------------------------- +// +TAccess CalcAccessModifier(HANodeIterator node) +{ + const XMLCh * ac = node.GetAttribute(KXMLAccessString); + + TAccess ret = EAccessGlobal; + + if ( !ac ) + { + ret = EAccessGlobal; + } + else if ( Equals(ac,KXMLPublicString) ) + { + ret = EAccessPublic; + } + else if ( Equals(ac,KXMLProtectedString) ) + { + ret = EAccessProtected; + } + else if ( Equals(ac,KXMLPrivateString) ) + { + ret = EAccessPrivate; + } + else + { + assert(false); + } + + return ret; + +} + +// ---------------------------------------------------------------------------- +// CheckAccessModifier +// ---------------------------------------------------------------------------- +// +bool CheckAccessModifier(HANodeIterator baseline,HANodeIterator current) +{ + TAccess baselineaccess = CalcAccessModifier(baseline); + TAccess currentaccess = CalcAccessModifier(current); + return CheckAccessModifier(baselineaccess,currentaccess); +} + +// ---------------------------------------------------------------------------- +// CheckAccessModifier +// ---------------------------------------------------------------------------- +// +bool CheckAccessModifier(TAccess baselineaccess,TAccess currentaccess) +{ + return (currentaccess <= baselineaccess); +} + +// ---------------------------------------------------------------------------- +// CompareNames +// ---------------------------------------------------------------------------- +// +bool CompareNames(HANodeIterator baseline, HANodeIterator current) +{ + const XMLCh * basename = baseline.GetAttribute(KXMLNameString); + const XMLCh * currentname = current.GetAttribute(KXMLNameString); + + if ( basename == NULL || currentname == NULL ) + { + return false; + } + + return Equals(basename,currentname); +} + +// ---------------------------------------------------------------------------- +// ClassIsDerivable +// ---------------------------------------------------------------------------- +// +bool ClassIsDerivable(HANodeIterator node) +{ + return ( + ( + node.CheckForBooleanAttribute(KXMLBBCPublicConstructorString) || + node.CheckForBooleanAttribute(KXMLBBCProtectedConstructorString) + )&& + ( + Equals(node.GetAttribute(KXMLBBCDestructorAccessString),KXMLBBCAccessPublicString) || + Equals(node.GetAttribute(KXMLBBCDestructorAccessString),KXMLBBCAccessProtectedString) + ) + ); + +} + +// ---------------------------------------------------------------------------- +// ClassIsInstantiable +// ---------------------------------------------------------------------------- +// +bool ClassIsInstantiable(HANodeIterator node) +{ + return node.CheckForBooleanAttribute(KXMLBBCPublicConstructorString) && + Equals(node.GetAttribute(KXMLBBCDestructorAccessString),KXMLBBCAccessPublicString); +} + + +// ---------------------------------------------------------------------------- +// FindParentContext +// ---------------------------------------------------------------------------- +// +bool FindParentContext(HANodeIterator memberNode, HANodeIterator& parentNode) +{ + if ( Equals(memberNode->getNodeName(),KXMLEnumValueString) ) + { + parentNode.current = memberNode->getParentNode(); + return true; + } + + const XMLCh* contextid = memberNode.GetAttribute(KXMLContextString); + + if (contextid) + { + bool ret = parentNode.FindNodeById(contextid); + return ret; + } + + return false; +} + +// ---------------------------------------------------------------------------- +// CheckAccessibility +// ---------------------------------------------------------------------------- +// +bool CheckAccessibility(HANodeIterator memberNode) +{ + bool dummy=false; + return CheckAccessibility(memberNode, dummy); +} + +// ---------------------------------------------------------------------------- +// CheckAccessibility +// ---------------------------------------------------------------------------- +// +bool CheckAccessibility(HANodeIterator memberNode, bool & exposedByInline) +{ + TAccess access = CalcAccessModifier(memberNode); + + HANodeIterator parentNode(memberNode); + if ( !FindParentContext(memberNode, parentNode) ) + { + // Not a member of a class, so this is accessible + return true; + } + + return CheckAccessibility(parentNode, exposedByInline, access); +} + +// ---------------------------------------------------------------------------- +// CheckAccessibility +// ---------------------------------------------------------------------------- +// +bool CheckAccessibility(HANodeIterator parentNode, bool & exposedByInline, TAccess access) +{ + if ( !CheckAccessibility(parentNode,exposedByInline) ) + { + return false; + } + + if ( EAccessPublic >= access ) + { + return true; + } + + if ( EAccessHidden == access ) + { + return false; + } + + if ( ClassIsDerivable(parentNode) ) + { + if ( EAccessProtected == access ) + { + // Protected methods are accessible by derived classes + return true; + } + + if ( + EAccessPrivate == access && + parentNode.CheckForBooleanAttribute(KXMLBBCProtectedInlineString) + ) + { + // Although this method is private, it might be possible that it + // is accessed by protected inline function. Because this is derivable + // class this private method might be exposed by the protected inline + // function. + exposedByInline = true; + return true; + } + } + + if ( parentNode.CheckForBooleanAttribute(KXMLBBCPublicInlineString) ) + { + // Class has public inline function(s) and it is possible that they + // are exposing some private stuff. + exposedByInline = true; + return true; + } + + return false; +} + +// ---------------------------------------------------------------------------- +// IsAnonymous +// ---------------------------------------------------------------------------- +// +bool IsAnonymous(HANodeIterator node) +{ + const XMLCh* nodename = node.GetAttribute(KXMLNameString); + + //If the name starts with the character KAnonymousName + // this is anonymous + if (nodename) + { + return StartsWith(nodename,KAnonymousName); + }else + { + return true; + } +} + +// ---------------------------------------------------------------------------- +// IsAnonymousType +// ---------------------------------------------------------------------------- +// +bool IsAnonymousType(HANodeIterator node) +{ + const XMLCh* nodetypeid = node.GetAttribute(KXMLTypeString); + + if (nodetypeid) + { + //The node has type attribute so check the parent type for + // anonymity + HANodeIterator typenode(node); + bool ret = typenode.FindNodeById(nodetypeid); + assert(ret); + + return IsAnonymousType(typenode); + } + + const XMLCh* nodename = node.GetAttribute(KXMLNameString); + const XMLCh* nodetypename = node->getNodeName(); + + if ( nodename ) + { + if ( Equals(KXMLEnumerationString, nodetypename) && IsAnonymous(node) ) + { + //This is anonymous enumeration + return true; + } + //The node does have name so this is not anonymous + return false; + } + + + if ( !Equals(KXMLUnionString, nodetypename) && + !Equals(KXMLStructString, nodetypename) && + !Equals(KXMLEnumerationString, nodetypename) ) + { + return false; + } + + //If there is no type and no name attributes the type is anonymous + return true; +} + +// ---------------------------------------------------------------------------- +// FindAnonymousType +// ---------------------------------------------------------------------------- +// +bool FindAnonymousType(HANodeIterator node, HANodeIterator& anonymousnode) +{ + const XMLCh* nodetypeid = node.GetAttribute(KXMLTypeString); + + if (nodetypeid) + { + //The node has type attribute so check the parent type for + // anonymity + HANodeIterator typenode(node); + bool ret = typenode.FindNodeById(nodetypeid); + assert(ret); + + return FindAnonymousType(typenode,anonymousnode); + } + + const XMLCh* nodename = node.GetAttribute(KXMLNameString); + const XMLCh* nodetypename = node->getNodeName(); + + if ( nodename && !(Equals(KXMLEnumerationString, nodetypename) && IsAnonymous(node)) ) + { + //The node does have name so this is not anonymous + return false; + } + + //If there is no type and no name attributes the type is anonymous + anonymousnode.current = node.current; + return true; +} + +// ---------------------------------------------------------------------------- +// ClassPrimaryBase +// ---------------------------------------------------------------------------- +// +bool ClassPrimaryBase(const HANodeIterator& classnode,HANodeIterator& primarybase ) +{ + //Iterate through the base classes + DOMNodeList* childs = classnode.GetElementsByTagName(KXMLBaseString); + + if (childs) + { + XMLSize_t childcount = childs->getLength(); + + for (unsigned int i = 0; i < childcount; ++i) + { + HANodeIterator classit(classnode); + classit.current = childs->item(i); + + //If the subclass' offset is zero, it is the primary base + if ( Equals( KXML0String, classit.GetAttribute(KXMLOffsetString)) ) + { + bool found = primarybase.FindNodeById(classit.GetAttribute(KXMLTypeString)); + assert(found); + + if ( primarybase.CheckForBooleanAttribute(KXMLBBCVirtualString) ) + { + return true; + } else + { + return false; + } + } + } + } + return false; +} + +// ---------------------------------------------------------------------------- +// ClassOrderMembers +// ---------------------------------------------------------------------------- +// +void ClassOrderMembers(HANodeIterator node, + vector& virtualMethods, + vector& inlineMethods, + vector& exportedMethods, + vector& methods, + vector& fields, + vector& others) +{ + const XMLCh* attributeValue = node.GetAttribute(KXMLMembersString); + if (attributeValue) + { + BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString(attributeValue); + auto_ptr > memberids(memberids_ptr); + + for (unsigned int i = 0; i < memberids->size(); ++i) + { + const XMLCh * memberid = memberids->elementAt(i); + + HANodeIterator member(node); + + if ( member.FindNodeById(memberid) ) + { + + if ( !IsProperNode(member) ) + { + continue; + } + //Put it in the right vector + const XMLCh* membernodename = member->getNodeName(); + assert(membernodename != NULL); + if ( IsFunction(member) ) + { + //Check for export + const XMLCh* attributeValue = member.GetAttribute(KXMLAttributeString); + bool normalMethod = true; + + //Check for virtuality + if ( member.CheckForBooleanAttribute(KXMLVirtualString) || + member.CheckForBooleanAttribute(KXMLPureVirtualString) ) + { + //printMember(member); + //DEBUG_PRINT(" is virtual member\n"); + //Method is virtual + virtualMethods.push_back(member.current); + normalMethod = false; + } + //Check for export + if ( attributeValue && Equals(attributeValue,KXMLExportedString) + ) + { + //printMember(member); + //DEBUG_PRINT(" is exported or inline method\n"); + //Method is exported + exportedMethods.push_back(member.current); + normalMethod = false; + } + //Check for inline + if ( member.CheckForBooleanAttribute(KXMLInlineString) + ) + { + //printMember(member); + //DEBUG_PRINT(" is exported or inline method\n"); + //Method is exported + inlineMethods.push_back(member.current); + normalMethod = false; + } + + //Normal method + if ( normalMethod ) + { + //printMember(member); + //DEBUG_PRINT(" is normal method\n"); + methods.push_back(member.current); + } + + } else if ( Equals(membernodename,KXMLFieldString) ) + { + //printMember(member); + //DEBUG_PRINT(" is field\n"); + fields.push_back(member.current); + + } else + { + //printMember(member); + //DEBUG_PRINT(" is other member\n"); + others.push_back(member.current); + } + + + } + else + { + //The tree is broken + assert(false); + } + } + + } +} + +// ---------------------------------------------------------------------------- +// ClassOrderMembers +// ---------------------------------------------------------------------------- +// +void ClassOrderMembers(HANodeIterator node, + vector& virtualMethods, + vector& inlineMethods, + vector& exportedMethods, + vector& exportedVirtualMethods, + vector& methods, + vector& fields, + vector& others) +{ + const XMLCh* attributeValue = node.GetAttribute(KXMLMembersString); + + if (attributeValue) + { + BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString(attributeValue); + auto_ptr > memberids(memberids_ptr); + + for (unsigned int i = 0; i < memberids->size(); ++i) + { + const XMLCh * memberid = memberids->elementAt(i); + + HANodeIterator member(node); + + if ( member.FindNodeById(memberid) ) + { + + if ( !IsProperNode(member) ) + { + continue; + } + //Put it in the right vector + const XMLCh* membernodename = member->getNodeName(); + assert(membernodename != NULL); + if ( IsFunction(member) ) + { + //Check for export + const XMLCh* attributeValue = member.GetAttribute(KXMLAttributeString); + bool normalMethod = true; + bool virtualMethod = false; + bool exportedMethod = false; + + //Check for virtuality + if ( member.CheckForBooleanAttribute(KXMLVirtualString) || + member.CheckForBooleanAttribute(KXMLPureVirtualString) ) + { + //printMember(member); + //DEBUG_PRINT(" is virtual member\n"); + //Method is virtual + virtualMethods.push_back(member.current); + normalMethod = false; + virtualMethod = true; + } + //Check for export + if ( attributeValue && Equals(attributeValue,KXMLExportedString) ) + { + //printMember(member); + //DEBUG_PRINT(" is exported or inline method\n"); + //Method is exported + exportedMethods.push_back(member.current); + normalMethod = false; + exportedMethod = true; + } + /*if (virtualMethod && exportedMethod) + { + virtualMethods.pop_back(); + exportedMethods.pop_back(); + exportedVirtualMethods.push_back(member.current); + }*/ + //Check for inline + if ( member.CheckForBooleanAttribute(KXMLInlineString) ) + { + //printMember(member); + //DEBUG_PRINT(" is exported or inline method\n"); + //Method is exported + inlineMethods.push_back(member.current); + normalMethod = false; + } + + //Normal method + if ( normalMethod ) + { + //printMember(member); + //DEBUG_PRINT(" is normal method\n"); + methods.push_back(member.current); + } + + } else if ( Equals(membernodename,KXMLFieldString) ) + { + //printMember(member); + //DEBUG_PRINT(" is field\n"); + fields.push_back(member.current); + + } else + { + //printMember(member); + //DEBUG_PRINT(" is other member\n"); + others.push_back(member.current); + } + + + } + else + { + //The tree is broken + assert(false); + } + } + + } +} + +// ---------------------------------------------------------------------------- +// ClassGenerateVirtualTable +// ---------------------------------------------------------------------------- +// +const NodeIndex::vtable_t& ClassGenerateVirtualTable(HANodeIterator& classnode) +{ + string vtablename = GenerateFullyQualifiedName(classnode); + + //Notice that this does not clear vtable, if one already exists + const NodeIndex::vtable_t* vtable = classnode.iNodeIndex.AddEmptyVirtualTable(vtablename); + + if ( 0 != vtable->size() ) + { + //The vtable already exists + return *vtable; + } + else + { + vector virtualMethods; + vector inlineMethods; + vector exportedMethods; + vector methods; + vector fields; + vector others; + + ClassOrderMembers(classnode, virtualMethods, inlineMethods, exportedMethods, + methods, fields, others); + + HANodeIterator primarybase(classnode); + //Lets check if we have primary base + if ( ClassPrimaryBase( classnode,primarybase ) ) + { + //First copy the virtual table of primary base + const NodeIndex::vtable_t& primvtable = ClassGenerateVirtualTable(primarybase); + if (primvtable.size()) + { + NodeIndex::vtable_t::const_iterator it = primvtable.begin(); + for (; it != primvtable.end(); ++it) + { + classnode.iNodeIndex.AddVirtualFunction(vtablename,it->first,it->second); + } + + //Then add the new virtual functions and overwritings of the other bases. + unsigned int i = 0; + for ( i = 0; i < virtualMethods.size(); ++i) + { + HANodeIterator functionnode(classnode); + functionnode.current = virtualMethods[i]; + + //We assume that the primary base includes virtual destructor so we can skip it + // here (it overwrites the place from primary base) + const XMLCh* nodetype = functionnode->getNodeName(); + if ( Equals(nodetype,KXMLDestructorString) ) + { + continue; + } + + string funcsig = GenerateFunctionSignature(functionnode); + + //Check the primary base for overwriting + NodeIndex::vtable_t::const_iterator it = primvtable.begin(); + for (; it != primvtable.end(); ++it) + { + if ( funcsig == it->first ) + { + //This function overwrites one from the primary base and is not added + //to the end of the vtable + break; + } + } + if ( it == primvtable.end() ) + { + //Function was not found from the primary base vtable and is added + //to the end of the table + classnode.iNodeIndex.AddVirtualFunction(vtablename,funcsig,functionnode.current); + } + } + } + }else + { + //We do not have primary base and we can construct the virtual table from clean start + unsigned int i = 0; + for ( i = 0; i < virtualMethods.size(); ++i) + { + HANodeIterator functionnode(classnode); + functionnode.current = virtualMethods[i]; + string funcsig = GenerateFunctionSignature(functionnode); + classnode.iNodeIndex.AddVirtualFunction(vtablename,funcsig,functionnode.current); + } + } + return *vtable; + } + +} + +// ---------------------------------------------------------------------------- +// ClassBaseSize +// ---------------------------------------------------------------------------- +// +int ClassBaseSize(const HANodeIterator& classnode, const NodeIndex::dtable_t& fields) +{ + //This is empty class + if ( 0 == fields.size() ) + { + return 8; + } + + DataMember lastmember = fields[fields.size()-1]; + + //The last member is virtual table pointer + if ( NULL == lastmember.iNode ) + { + return lastmember.iOffset + 32; + } + + HANodeIterator lastfield(classnode); + lastfield.current = lastmember.iNode; + + const XMLCh* type = lastfield.GetAttribute(KXMLTypeString); + assert(type); + HANodeIterator typenode(classnode); + bool typefound = typenode.FindNodeById(type); + assert(typefound); + const XMLCh * nodetype = typenode->getNodeName(); + assert(nodetype); + + int fieldsize_int = 0; + //If the last member is class, get the base size for it + if ( Equals(nodetype,KXMLStructString) || Equals(nodetype,KXMLClassString) ) + { + const NodeIndex::dtable_t& fields = ClassGenerateDataMemberTable(typenode); + fieldsize_int = ClassBaseSize(typenode,fields); + }else + { + const XMLCh* fieldsize = GetSize(lastfield); + assert( fieldsize ); + string fieldsize_str = toString(fieldsize); + fieldsize_int = atoi(fieldsize_str.c_str()); + } + + /*const XMLCh* offset = lastfield.GetAttribute(KXMLOffsetString); + + assert( offset ); + + string offset_str = toString(offset); + + int offset_int = atoi(offset_str.c_str());*/ + + return fieldsize_int+lastmember.iOffset;//offset_int; +} + +// ---------------------------------------------------------------------------- +// ClassGenerateDataMemberTable +// ---------------------------------------------------------------------------- +// +const NodeIndex::dtable_t& ClassGenerateDataMemberTable(const HANodeIterator& classnode) +{ + string dtablename = GenerateFullyQualifiedName(classnode); + //Notice that this does not clear dtable, if one already exists + const NodeIndex::dtable_t* dtable = classnode.iNodeIndex.AddEmptyDataMemberTable(classnode, dtablename); + + if ( 0 != dtable->size() ) + { + //The vtable already exists + return *dtable; + } + else + { + + //Lets check if we are dynamic class so that we need to add + // the virtual table pointer + if ( classnode.CheckForBooleanAttribute(KXMLBBCVirtualString) ) + { + string name = "::vtableptr"; + int lineNo = 0; + string line_str = toString(classnode.GetAttribute(KXMLLineString)); + if(line_str.size() > 0) + lineNo = atoi(line_str.c_str()); + classnode.iNodeIndex.AddDataMember(classnode,dtablename,name,NULL,0,EAccessGlobal,lineNo); + } + + //Add the fields from bases + DOMNodeList* childs = classnode.GetElementsByTagName(KXMLBaseString); + if (childs) + { + XMLSize_t childcount = childs->getLength(); + + for (unsigned int i = 0; i < childcount; ++i) + { + HANodeIterator classit(classnode); + classit.current = childs->item(i); + + HANodeIterator baseclass(classnode); + bool found = baseclass.FindNodeById(classit.GetAttribute(KXMLTypeString)); + assert(found); + + if ( baseclass.CheckForBooleanAttribute(KXMLBBCVirtualString) ) + { + string offset_str = toString(classit.GetAttribute(KXMLOffsetString)); + int offset = atoi(offset_str.c_str()); + //Change offset from bytes to bits + offset = offset*8; + int lineNo = 0; + string line_str = toString(classit.GetAttribute(KXMLLineString)); + lineNo = atoi(line_str.c_str()); + + string name = "["; + name += GenerateFullyQualifiedName(baseclass); + name += "::vtableptr"; + name += "]"; + classnode.iNodeIndex.AddDataMember(classnode,dtablename,name,NULL,offset,EAccessGlobal,lineNo); + } + } + } + + //Add the current members + vector virtualMethods; + vector inlineMethods; + vector exportedMethods; + vector methods; + vector fields; + vector others; + + ClassOrderMembers(classnode, virtualMethods, inlineMethods, exportedMethods, + methods, fields, others); + + unsigned int i = 0; + for ( i = 0; i < fields.size(); ++i) + { + HANodeIterator fieldnode(classnode); + fieldnode.current = fields[i]; + string offset_str = toString(fieldnode.GetAttribute(KXMLOffsetString)); + int offset = atoi(offset_str.c_str()); + + const XMLCh* ch_name = fieldnode.GetAttribute(KXMLNameString); + string name = "::"; //GenerateFullyQualifiedName(fieldnode); + if (ch_name) + { + name += toString(ch_name); + } + + int lineNo = 0; + string line_str = toString(fieldnode.GetAttribute(KXMLLineString)); + lineNo = atoi(line_str.c_str()); + + TAccess access = CalcAccessModifier(fieldnode); + classnode.iNodeIndex.AddDataMember(classnode,dtablename,name,fieldnode.current,offset,access,lineNo); + } + return *dtable; + + } + +} + +int ParseXMLFile( const string& xmlFilename, + XERCES_CPP_NAMESPACE_QUALIFIER DOMBuilder*& domParser, + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument*& domDocument, + XERCES_CPP_NAMESPACE_QUALIFIER DOMNode*& domRootNode ) +{ + int ret = 0; + + if( BBCFileUtils::FileExists(xmlFilename) == false ) + throw HAException(string("File: ") + xmlFilename + string(" cannot be found!\n")); + + static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull }; + DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(gLS); + domParser = ((DOMImplementationLS*)impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0); + XMLModuleErrorHandler errorHandler; + domParser->setErrorHandler(&errorHandler); + XMLCh * nowhitespace = XMLString::transcode("whitespace-in-element-content"); + domParser->setFeature(nowhitespace,false); + XMLString::release(&nowhitespace); + + try { + domDocument = domParser->parseURI(xmlFilename.c_str()); + } catch (XMLException& exception) { + + if (domParser != NULL) { + domParser->release(); + domParser = 0; + } + if (domDocument != NULL) { + domDocument = NULL; + } + domRootNode = NULL; + ret = -1; + cout << "XML ERROR: " << exception.getMessage(); + return ret; + } + if (domDocument != NULL) + { + domRootNode = (DOMNode*)domDocument->getDocumentElement(); + if( domRootNode == 0 ) + throw HAException(string("\nXML ERROR: Root element missing from ") + xmlFilename + "\n"); + } + else + { + throw HAException(string("File: ") + xmlFilename + string(" could not be parsed! Please, check the filename.\n")); + } + return ret; +} + +string& toLower(string& name) +{ +#ifdef __WIN__ + string::iterator it(name.begin()); + + for(; it != name.end(); ++it) + { + *it = tolower((unsigned char)*it); + } +#endif + return name; +}