element and attribute code compiling
diff --git a/tinyxml2.cpp b/tinyxml2.cpp
index ae6a747..a11be4b 100644
--- a/tinyxml2.cpp
+++ b/tinyxml2.cpp
@@ -31,69 +31,8 @@
 }

 

 

-// --------- XMLNode ----------- //

-

-XMLNode::XMLNode( XMLDocument* doc ) :

-	document( doc ),

-	parent( 0 ),

-	firstChild( 0 ), lastChild( 0 ),

-	prev( 0 ), next( 0 )

-{

-

-}

-

-

-XMLNode::~XMLNode()

-{

-	XMLNode* node=firstChild;

-	while( node ) {

-		XMLNode* temp = node->next;

-		delete node;

-		node = temp;

-	}

-}

-

-

-XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )

-{

-	if ( lastChild ) {

-		TIXMLASSERT( firstChild );

-		TIXMLASSERT( lastChild->next == 0 );

-		lastChild->next = addThis;

-		addThis->prev = lastChild;

-		lastChild = addThis;

-

-		addThis->parent = this;

-		addThis->next = 0;

-	}

-	else {

-		TIXMLASSERT( firstChild == 0 );

-		firstChild = lastChild = addThis;

-

-		addThis->parent = this;

-		addThis->prev = 0;

-		addThis->next = 0;

-	}

-	return addThis;

-}

-

-

-void XMLNode::Print( FILE* fp, int depth )

-{

-	for( XMLNode* node = firstChild; node; node=node->next ) {

-		node->Print( fp, depth );

-	}

-}

-

-void XMLNode::PrintSpace( FILE* fp, int depth ) 

-{

-	for( int i=0; i<depth; ++i ) {

-		fprintf( fp, "    " );

-	}

-}

-

-

-const char* XMLNode::ParseText( char* p, const char* endTag, char** next )

+// --------- XMLBase ----------- //

+const char* XMLBase::ParseText( char* p, const char* endTag, char** next )

 {

 	TIXMLASSERT( endTag && *endTag );

 

@@ -102,6 +41,7 @@
 	char  endChar = *endTag;

 	int   length = strlen( endTag );	

 	char* nextTag = 0;

+	*next = 0;

 

 	// Inner loop of text parsing.

 	while ( *p ) {

@@ -148,16 +88,159 @@
 }

 

 

+const char* XMLBase::ParseName( char* p, char** next )

+{

+	char* start = p;

+	char* nextTag = 0;

+	*next = 0;

+

+	start = p;

+	if ( !start || !(*start) ) {

+		return 0;

+	}

+

+	if ( !IsAlpha( *p ) ) {

+		return 0;

+	}

+

+	while( *p && (

+			   IsAlphaNum( (unsigned char) *p ) 

+			|| *p == '_'

+			|| *p == '-'

+			|| *p == '.'

+			|| *p == ':' ))

+	{

+		++p;

+	}

+	*p = 0;

+

+	if ( p > start ) {

+		*next = p;

+		return start;

+	}

+	return p+1;

+}

+

+

+char* XMLBase::Identify( XMLDocument* document, char* p, XMLNode** node ) 

+{

+	XMLNode* returnNode = 0;

+

+	p = XMLNode::SkipWhiteSpace( p );

+	if( !p || !*p || *p != '<' )

+	{

+		return 0;

+	}

+

+	// What is this thing? 

+	// - Elements start with a letter or underscore, but xml is reserved.

+	// - Comments: <!--

+	// - Decleration: <?xml

+	// - Everthing else is unknown to tinyxml.

+	//

+

+	static const char* xmlHeader		= { "<?xml" };

+	static const char* commentHeader	= { "<!--" };

+	static const char* dtdHeader		= { "<!" };

+	static const char* cdataHeader		= { "<![CDATA[" };

+

+	static const int xmlHeaderLen		= 5;

+	static const int commentHeaderLen	= 4;

+	static const int dtdHeaderLen		= 2;

+	static const int cdataHeaderLen		= 9;

+

+	if ( XMLNode::StringEqual( p, commentHeader, commentHeaderLen ) ) {

+		returnNode = new XMLComment( document );

+		p += commentHeaderLen;

+	}

+	else {

+		TIXMLASSERT( 0 );

+	}

+

+	*node = returnNode;

+	return p;

+}

+

+

+// --------- XMLNode ----------- //

+

+XMLNode::XMLNode( XMLDocument* doc ) :

+	document( doc ),

+	parent( 0 ),

+	firstChild( 0 ), lastChild( 0 ),

+	prev( 0 ), next( 0 )

+{

+

+}

+

+

+XMLNode::~XMLNode()

+{

+	XMLNode* node=firstChild;

+	while( node ) {

+		XMLNode* temp = node->next;

+		delete node;

+		node = temp;

+	}

+	if ( prev ) {

+		prev->next = next;

+	}

+	if ( next ) {

+		next->prev = prev;

+	}

+}

+

+

+XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )

+{

+	if ( lastChild ) {

+		TIXMLASSERT( firstChild );

+		TIXMLASSERT( lastChild->next == 0 );

+		lastChild->next = addThis;

+		addThis->prev = lastChild;

+		lastChild = addThis;

+

+		addThis->parent = this;

+		addThis->next = 0;

+	}

+	else {

+		TIXMLASSERT( firstChild == 0 );

+		firstChild = lastChild = addThis;

+

+		addThis->parent = this;

+		addThis->prev = 0;

+		addThis->next = 0;

+	}

+	return addThis;

+}

+

+

+void XMLNode::Print( FILE* fp, int depth )

+{

+	for( XMLNode* node = firstChild; node; node=node->next ) {

+		node->Print( fp, depth );

+	}

+}

+

+void XMLNode::PrintSpace( FILE* fp, int depth ) 

+{

+	for( int i=0; i<depth; ++i ) {

+		fprintf( fp, "    " );

+	}

+}

+

+

+

+

 // --------- XMLComment ---------- //

 

-XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )

+XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ), value( 0 )

 {

 }

 

 

 XMLComment::~XMLComment()

 {

-

 }

 

 

@@ -176,6 +259,132 @@
 }

 

 

+// --------- XMLAttribute ---------- //

+char* XMLAttribute::ParseDeep( char* p )

+{

+	char endTag[2] = { *p, 0 };

+	++p;

+	value = ParseText( p, endTag, &p );

+	if ( !value ) return 0;

+	return p;

+}

+

+

+// --------- XMLElement ---------- //

+XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),

+	name( 0 ),

+	closing( false ),

+	rootAttribute( 0 ),

+	lastAttribute( 0 )

+{

+}

+

+

+XMLElement::~XMLElement()

+{

+	XMLAttribute* attribute = rootAttribute;

+	while( attribute ) {

+		XMLAttribute* next = attribute->next;

+		delete attribute;

+		attribute = next;

+	}

+

+	XMLNode* child = firstChild;

+	while( child ) {

+		XMLNode* next = child->next;

+		delete child;

+		child = next;

+	}

+}

+

+

+char* XMLElement::ParseDeep( char* p )

+{

+	// Read the element name.

+	p = SkipWhiteSpace( p );

+	if ( !p ) return 0;

+	const char* start = p;

+

+	// The closing element is the </element> form. It is

+	// parsed just like a regular element then deleted from

+	// the DOM.

+	if ( *p == '/' ) {

+		closing = true;

+		++p;

+	}

+

+	name = ParseName( p, &p );

+	if ( !name ) return 0;

+

+	// Read the attributes.

+	while( p ) {

+		p = SkipWhiteSpace( p );

+		if ( !p || !(*p) ) {

+			document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, name );

+			return 0;

+		}

+		const char* saveP = p;

+

+		// attribute.

+		if ( *p == '\'' || *p == '\"' ) {

+			XMLAttribute* attrib = new XMLAttribute( this );

+			p = attrib->ParseDeep( p );

+			if ( !p ) {

+				delete attrib;

+				document->SetError( XMLDocument::ERROR_PARSING_ATTRIBUTE, start, saveP );

+				return 0;

+			}

+			if ( rootAttribute ) {

+				TIXMLASSERT( lastAttribute );

+				lastAttribute->next = attrib;

+				lastAttribute = attrib;

+			}

+			else {

+				rootAttribute = lastAttribute = attrib;

+			}

+		}

+		else if ( *p == '/' && *(p+1) == '>' ) {

+			// end tag.

+			if ( closing ) {

+				document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p );

+				return 0;

+			}

+			return p+2;	// done; sealed element.

+		}

+		else if ( *p == '>' ) {

+			++p;

+			break;

+		}

+	}

+

+	while( p && *p ) {

+		XMLNode* node = 0;

+		p = Identify( document, p, &node );

+		if ( p && node ) {

+			node->ParseDeep( p );

+

+			XMLElement* element = node->ToElement();

+			if ( element && element->Closing() ) {

+				if ( StringEqual( element->Name(), this->Name() ) ) {

+					// All good, this is closing tag.

+					delete node;

+					p = 0;

+				}

+				else {

+					document->SetError( XMLDocument::ERROR_PARSING_ELEMENT, start, p );

+					delete node;

+				}

+				return p;

+			}

+			else {

+				this->InsertEndChild( node );

+			}

+		}

+	}

+	return 0;

+}

+

+

 // --------- XMLDocument ----------- //

 XMLDocument::XMLDocument() : 

 	charBuffer( 0 )

@@ -197,7 +406,7 @@
 	charBuffer = CharBuffer::Construct( p );

 	XMLNode* node = 0;

 	

-	char* q = Identify( charBuffer->mem, &node );

+	char* q = Identify( this, charBuffer->mem, &node );

 	root->InsertEndChild( node );

 	node->ParseDeep( q );

 

@@ -213,41 +422,3 @@
 }

 

 

-char* XMLDocument::Identify( char* p, XMLNode** node ) 

-{

-	XMLNode* returnNode = 0;

-

-	p = XMLNode::SkipWhiteSpace( p );

-	if( !p || !*p || *p != '<' )

-	{

-		return 0;

-	}

-

-	// What is this thing? 

-	// - Elements start with a letter or underscore, but xml is reserved.

-	// - Comments: <!--

-	// - Decleration: <?xml

-	// - Everthing else is unknown to tinyxml.

-	//

-

-	static const char* xmlHeader = { "<?xml" };

-	static const char* commentHeader = { "<!--" };

-	static const char* dtdHeader = { "<!" };

-	static const char* cdataHeader = { "<![CDATA[" };

-

-	static const int xmlHeaderLen = 5;

-	static const int commentHeaderLen = 4;

-	static const int dtdHeaderLen = 2;

-	static const int cdataHeaderLen = 9;

-

-	if ( XMLNode::StringEqual( p, commentHeader, commentHeaderLen ) ) {

-		returnNode = new XMLComment( this );

-		p += commentHeaderLen;

-	}

-	else {

-		TIXMLASSERT( 0 );

-	}

-

-	*node = returnNode;

-	return p;

-}