blob: 9f61a6bb7226f7f5d54fb778e8f1bd2534bfa64d [file] [log] [blame]
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001#include "tinyxml2.h"
2
3#include <stdio.h>
4#include <stdlib.h>
Lee Thomasonec5a7b42012-02-13 18:16:52 -08005#include <string.h>
U-Lama\Leee13c3e62011-12-28 14:36:55 -08006
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -08007#if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -08008 #include <crtdbg.h>
9 _CrtMemState startMemState;
10 _CrtMemState endMemState;
11#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -080012
U-Lama\Leee13c3e62011-12-28 14:36:55 -080013using namespace tinyxml2;
Lee Thomasonec5a7b42012-02-13 18:16:52 -080014int gPass = 0;
15int gFail = 0;
16
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080017
U-Stream\Lee09a11c52012-02-17 08:31:16 -080018bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080019{
20 bool pass = !strcmp( expected, found );
21 if ( pass )
22 printf ("[pass]");
23 else
24 printf ("[fail]");
25
U-Stream\Lee09a11c52012-02-17 08:31:16 -080026 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080027 printf (" %s\n", testString);
28 else
29 printf (" %s [%s][%s]\n", testString, expected, found);
30
31 if ( pass )
32 ++gPass;
33 else
34 ++gFail;
35 return pass;
36}
37
38
U-Stream\Lee09a11c52012-02-17 08:31:16 -080039bool XMLTest( const char* testString, int expected, int found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080040{
41 bool pass = ( expected == found );
42 if ( pass )
43 printf ("[pass]");
44 else
45 printf ("[fail]");
46
U-Stream\Lee09a11c52012-02-17 08:31:16 -080047 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080048 printf (" %s\n", testString);
49 else
50 printf (" %s [%d][%d]\n", testString, expected, found);
51
52 if ( pass )
53 ++gPass;
54 else
55 ++gFail;
56 return pass;
57}
Lee Thomasonec5a7b42012-02-13 18:16:52 -080058
U-Lama\Leee13c3e62011-12-28 14:36:55 -080059
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -080060void NullLineEndings( char* p )
61{
62 while( p && *p ) {
63 if ( *p == '\n' || *p == '\r' ) {
64 *p = 0;
65 return;
66 }
67 ++p;
68 }
69}
70
71
Lee Thomason (grinliz)9b093cc2012-02-25 21:30:18 -080072int main( int /*argc*/, const char* /*argv*/ )
U-Lama\Leee13c3e62011-12-28 14:36:55 -080073{
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -080074 #if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -080075 _CrtMemCheckpoint( &startMemState );
76 #endif
Lee Thomason8a5dfee2012-01-18 17:43:40 -080077
Lee Thomason8a5dfee2012-01-18 17:43:40 -080078 {
Lee Thomason43f59302012-02-06 18:18:11 -080079 static const char* test[] = { "<element />",
80 "<element></element>",
81 "<element><subelement/></element>",
82 "<element><subelement></subelement></element>",
83 "<element><subelement><subsub/></subelement></element>",
84 "<!--comment beside elements--><element><subelement></subelement></element>",
85 "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
86 "<element attrib1='foo' attrib2=\"bar\" ></element>",
87 "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
88 "<element>Text inside element.</element>",
89 "<element><b></b></element>",
90 "<element>Text inside and <b>bolded</b> in the element.</element>",
91 "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
Lee Thomason8ee79892012-01-25 17:44:30 -080092 "<element>This &amp; That.</element>",
Lee Thomason18d68bd2012-01-26 18:17:26 -080093 "<element attrib='This&lt;That' />",
Lee Thomasondadcdfa2012-01-18 17:55:48 -080094 0
95 };
Lee Thomason6ee99fc2012-01-21 18:45:16 -080096 for( int i=0; test[i]; ++i ) {
Lee Thomasondadcdfa2012-01-18 17:55:48 -080097 XMLDocument doc;
Lee Thomason6ee99fc2012-01-21 18:45:16 -080098 doc.Parse( test[i] );
Lee Thomason5cae8972012-01-24 18:03:07 -080099 doc.Print();
Lee Thomasonec975ce2012-01-23 11:42:06 -0800100 printf( "----------------------------------------------\n" );
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800101 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800102 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800103#if 1
Lee Thomasond6277762012-02-22 16:00:12 -0800104 {
105 static const char* test = "<!--hello world\n"
106 " line 2\r"
107 " line 3\r\n"
108 " line 4\n\r"
109 " line 5\r-->";
110
111 XMLDocument doc;
112 doc.Parse( test );
113 doc.Print();
114 }
115
Lee Thomason2c85a712012-01-31 08:24:24 -0800116 {
117 static const char* test = "<element>Text before.</element>";
118 XMLDocument doc;
119 doc.Parse( test );
120 XMLElement* root = doc.FirstChildElement();
121 XMLElement* newElement = doc.NewElement( "Subelement" );
122 root->InsertEndChild( newElement );
123 doc.Print();
124 }
Lee Thomasond1983222012-02-06 08:41:24 -0800125 {
126 XMLDocument* doc = new XMLDocument();
127 static const char* test = "<element><sub/></element>";
128 doc->Parse( test );
129 delete doc;
130 }
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800131 {
Lee Thomason1ff38e02012-02-14 18:18:16 -0800132 // Test: Programmatic DOM
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800133 // Build:
134 // <element>
135 // <!--comment-->
136 // <sub attrib="1" />
137 // <sub attrib="2" />
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800138 // <sub attrib="3" >& Text!</sub>
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800139 // <element>
140
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800141 XMLDocument* doc = new XMLDocument();
Lee Thomason1ff38e02012-02-14 18:18:16 -0800142 XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
143
144 XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
145 for( int i=0; i<3; ++i ) {
146 sub[i]->SetAttribute( "attrib", i );
147 }
148 element->InsertEndChild( sub[2] );
149 XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
150 element->InsertAfterChild( comment, sub[0] );
151 element->InsertAfterChild( sub[0], sub[1] );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800152 sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800153 doc->Print();
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800154 XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
155 XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
156 XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
157 XMLTest( "Programmatic DOM", "& Text!",
158 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800159
160 // And now deletion:
161 element->DeleteChild( sub[2] );
162 doc->DeleteNode( comment );
163
164 element->FirstChildElement()->SetAttribute( "attrib", true );
165 element->LastChildElement()->DeleteAttribute( "attrib" );
166
167 XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
168 int value = 10;
169 int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
170 XMLTest( "Programmatic DOM", result, NO_ATTRIBUTE );
171 XMLTest( "Programmatic DOM", value, 10 );
172
173 doc->Print();
174
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800175 XMLPrinter streamer;
U-Stream\Leeae25a442012-02-17 17:48:16 -0800176 doc->Print( &streamer );
177 printf( "%s", streamer.CStr() );
178
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800179 delete doc;
180 }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800181 {
182 // Test: Dream
183 // XML1 : 1,187,569 bytes in 31,209 allocations
184 // XML2 : 469,073 bytes in 323 allocations
185 //int newStart = gNew;
186 XMLDocument doc;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800187 doc.LoadFile( "dream.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800188
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800189 doc.SaveFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800190 doc.PrintError();
191
192 XMLTest( "Dream", "xml version=\"1.0\"",
193 doc.FirstChild()->ToDeclaration()->Value() );
194 XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
195 XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
196 doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
197 XMLTest( "Dream", "And Robin shall restore amends.",
198 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
199 XMLTest( "Dream", "And Robin shall restore amends.",
200 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
201
202 XMLDocument doc2;
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800203 doc2.LoadFile( "dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800204 XMLTest( "Dream-out", "xml version=\"1.0\"",
205 doc2.FirstChild()->ToDeclaration()->Value() );
206 XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
207 XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
208 doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
209 XMLTest( "Dream-out", "And Robin shall restore amends.",
210 doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
211
212 //gNewTotal = gNew - newStart;
213 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800214 {
215 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
216 "<passages count=\"006\" formatversion=\"20020620\">\n"
217 " <wrong error>\n"
218 "</passages>";
219
220 XMLDocument doc;
221 doc.Parse( error );
222 XMLTest( "Bad XML", doc.ErrorID(), ERROR_PARSING_ATTRIBUTE );
223 }
224
225 {
226 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
227
228 XMLDocument doc;
229 doc.Parse( str );
230
231 XMLElement* ele = doc.FirstChildElement();
232
233 int iVal, result;
234 double dVal;
235
236 result = ele->QueryDoubleAttribute( "attr0", &dVal );
237 XMLTest( "Query attribute: int as double", result, XML_NO_ERROR );
238 XMLTest( "Query attribute: int as double", (int)dVal, 1 );
239 result = ele->QueryDoubleAttribute( "attr1", &dVal );
240 XMLTest( "Query attribute: double as double", (int)dVal, 2 );
241 result = ele->QueryIntAttribute( "attr1", &iVal );
242 XMLTest( "Query attribute: double as int", result, XML_NO_ERROR );
243 XMLTest( "Query attribute: double as int", iVal, 2 );
244 result = ele->QueryIntAttribute( "attr2", &iVal );
245 XMLTest( "Query attribute: not a number", result, WRONG_ATTRIBUTE_TYPE );
246 result = ele->QueryIntAttribute( "bar", &iVal );
247 XMLTest( "Query attribute: does not exist", result, NO_ATTRIBUTE );
248 }
249
250 {
251 const char* str = "<doc/>";
252
253 XMLDocument doc;
254 doc.Parse( str );
255
256 XMLElement* ele = doc.FirstChildElement();
257
258 int iVal;
259 double dVal;
260
261 ele->SetAttribute( "str", "strValue" );
262 ele->SetAttribute( "int", 1 );
263 ele->SetAttribute( "double", -1.0 );
264
265 const char* cStr = ele->Attribute( "str" );
266 ele->QueryIntAttribute( "int", &iVal );
267 ele->QueryDoubleAttribute( "double", &dVal );
268
269 XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
270 XMLTest( "Attribute round trip. int.", 1, iVal );
271 XMLTest( "Attribute round trip. double.", -1, (int)dVal );
272 }
273
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800274 {
275 XMLDocument doc;
276 doc.LoadFile( "utf8test.xml" );
277
278 // Get the attribute "value" from the "Russian" element and check it.
279 XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
280 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
281 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
282
283 XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
284
285 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
286 0xd1U, 0x81U, 0xd1U, 0x81U,
287 0xd0U, 0xbaU, 0xd0U, 0xb8U,
288 0xd0U, 0xb9U, 0 };
289 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
290
291 XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
292 XMLTest( "UTF-8: Browsing russian element name.",
293 russianText,
294 text->Value() );
295
296 // Now try for a round trip.
297 doc.SaveFile( "utf8testout.xml" );
298
299 // Check the round trip.
300 char savedBuf[256];
301 char verifyBuf[256];
302 int okay = 0;
303
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800304
305#pragma warning ( push )
306#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800307 FILE* saved = fopen( "utf8testout.xml", "r" );
308 FILE* verify = fopen( "utf8testverify.xml", "r" );
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800309#pragma warning ( pop )
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800310
311 if ( saved && verify )
312 {
313 okay = 1;
314 while ( fgets( verifyBuf, 256, verify ) )
315 {
316 fgets( savedBuf, 256, saved );
317 NullLineEndings( verifyBuf );
318 NullLineEndings( savedBuf );
319
320 if ( strcmp( verifyBuf, savedBuf ) )
321 {
322 printf( "verify:%s<\n", verifyBuf );
323 printf( "saved :%s<\n", savedBuf );
324 okay = 0;
325 break;
326 }
327 }
328 }
329 if ( saved )
330 fclose( saved );
331 if ( verify )
332 fclose( verify );
333 XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
334 }
335
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800336 // --------GetText()-----------
337 {
338 const char* str = "<foo>This is text</foo>";
339 XMLDocument doc;
340 doc.Parse( str );
341 const XMLElement* element = doc.RootElement();
342
343 XMLTest( "GetText() normal use.", "This is text", element->GetText() );
344
345 str = "<foo><b>This is text</b></foo>";
346 doc.Parse( str );
347 element = doc.RootElement();
348
349 XMLTest( "GetText() contained element.", element->GetText() == 0, true );
350 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800351
Lee Thomasond6277762012-02-22 16:00:12 -0800352
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800353 // ---------- CDATA ---------------
354 {
355 const char* str = "<xmlElement>"
356 "<![CDATA["
357 "I am > the rules!\n"
358 "...since I make symbolic puns"
359 "]]>"
360 "</xmlElement>";
361 XMLDocument doc;
362 doc.Parse( str );
363 doc.Print();
Lee Thomasond6277762012-02-22 16:00:12 -0800364
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800365 XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
366 "I am > the rules!\n...since I make symbolic puns",
Lee Thomasond6277762012-02-22 16:00:12 -0800367 false );
368 }
369
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800370 // ----------- CDATA -------------
371 {
372 const char* str = "<xmlElement>"
373 "<![CDATA["
374 "<b>I am > the rules!</b>\n"
375 "...since I make symbolic puns"
376 "]]>"
377 "</xmlElement>";
378 XMLDocument doc;
379 doc.Parse( str );
380 doc.Print();
381
382 XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
383 "<b>I am > the rules!</b>\n...since I make symbolic puns",
384 false );
385 }
386
387 // InsertAfterChild causes crash.
388 {
389 // InsertBeforeChild and InsertAfterChild causes crash.
390 XMLDocument doc;
391 XMLElement* parent = doc.NewElement( "Parent" );
392 doc.InsertFirstChild( parent );
393
394 XMLElement* childText0 = doc.NewElement( "childText0" );
395 XMLElement* childText1 = doc.NewElement( "childText1" );
396
397 XMLNode* childNode0 = parent->InsertEndChild( childText0 );
398 XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
399
400 XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true );
401 }
Lee Thomasond6277762012-02-22 16:00:12 -0800402
403 {
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800404 // Entities not being written correctly.
405 // From Lynn Allen
Lee Thomasond6277762012-02-22 16:00:12 -0800406
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800407 const char* passages =
408 "<?xml version=\"1.0\" standalone=\"no\" ?>"
409 "<passages count=\"006\" formatversion=\"20020620\">"
410 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
411 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
412 "</passages>";
Lee Thomasond6277762012-02-22 16:00:12 -0800413
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800414 XMLDocument doc;
415 doc.Parse( passages );
416 XMLElement* psg = doc.RootElement()->FirstChildElement();
417 const char* context = psg->Attribute( "context" );
418 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
Lee Thomasond6277762012-02-22 16:00:12 -0800419
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800420 XMLTest( "Entity transformation: read. ", expected, context, true );
Lee Thomasond6277762012-02-22 16:00:12 -0800421
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800422#pragma warning ( push )
423#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800424 FILE* textfile = fopen( "textfile.txt", "w" );
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800425#pragma warning ( pop )
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800426 if ( textfile )
427 {
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800428 XMLPrinter streamer( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800429 psg->Accept( &streamer );
430 fclose( textfile );
431 }
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800432#pragma warning ( push )
433#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated.
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800434 textfile = fopen( "textfile.txt", "r" );
Lee Thomason (grinliz)5ce4d972012-02-26 21:14:23 -0800435#pragma warning ( pop )
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800436 TIXMLASSERT( textfile );
437 if ( textfile )
438 {
439 char buf[ 1024 ];
440 fgets( buf, 1024, textfile );
441 XMLTest( "Entity transformation: write. ",
442 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
443 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.\"/>\n",
444 buf, false );
445 }
446 fclose( textfile );
447 }
448
449 {
450 const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
451
452 XMLDocument doc;
453 doc.Parse( test );
454 XMLTest( "dot in names", doc.Error(), 0);
455 XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
456 XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
457 }
458
459 {
460 const char* test = "<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>";
461
462 XMLDocument doc;
463 doc.Parse( test );
464
465 XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
466 XMLTest( "Entity with one digit.",
467 text->Value(), "1.1 Start easy ignore fin thickness\n",
468 false );
469 }
470
471 {
472 // DOCTYPE not preserved (950171)
473 //
474 const char* doctype =
475 "<?xml version=\"1.0\" ?>"
476 "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
477 "<!ELEMENT title (#PCDATA)>"
478 "<!ELEMENT books (title,authors)>"
479 "<element />";
480
481 XMLDocument doc;
482 doc.Parse( doctype );
483 doc.SaveFile( "test7.xml" );
484 doc.DeleteChild( doc.RootElement() );
485 doc.LoadFile( "test7.xml" );
486 doc.Print();
487
488 const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
489 XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
490
491 }
492
493 {
494 // Comments do not stream out correctly.
495 const char* doctype =
496 "<!-- Somewhat<evil> -->";
497 XMLDocument doc;
498 doc.Parse( doctype );
499
500 XMLComment* comment = doc.FirstChild()->ToComment();
501
502 XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
503 }
504 {
505 // Double attributes
506 const char* doctype = "<element attr='red' attr='blue' />";
507
508 XMLDocument doc;
509 doc.Parse( doctype );
510
511 XMLTest( "Parsing repeated attributes.", ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
512 }
513
514 {
515 // Embedded null in stream.
516 const char* doctype = "<element att\0r='red' attr='blue' />";
517
518 XMLDocument doc;
519 doc.Parse( doctype );
520 XMLTest( "Embedded null throws error.", true, doc.Error() );
521 }
522
523 {
524 // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
525 const char* str = " ";
526 XMLDocument doc;
527 doc.Parse( str );
528 XMLTest( "Empty document error", ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
529 }
530
531 {
532 // Low entities
533 XMLDocument doc;
534 doc.Parse( "<test>&#x0e;</test>" );
535 const char result[] = { 0x0e, 0 };
536 XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result );
537 doc.Print();
538 }
539
540 {
541 // Attribute values with trailing quotes not handled correctly
542 XMLDocument doc;
543 doc.Parse( "<foo attribute=bar\" />" );
544 XMLTest( "Throw error with bad end quotes.", doc.Error(), true );
545 }
546
547 {
548 // [ 1663758 ] Failure to report error on bad XML
549 XMLDocument xml;
550 xml.Parse("<x>");
551 XMLTest("Missing end tag at end of input", xml.Error(), true);
552 xml.Parse("<x> ");
553 XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
554 xml.Parse("<x></y>");
555 XMLTest("Mismatched tags", xml.ErrorID(), ERROR_MISMATCHED_ELEMENT);
556 }
557
558
559 {
560 // [ 1475201 ] TinyXML parses entities in comments
561 XMLDocument xml;
562 xml.Parse("<!-- declarations for <head> & <body> -->"
563 "<!-- far &amp; away -->" );
564
565 XMLNode* e0 = xml.FirstChild();
566 XMLNode* e1 = e0->NextSibling();
567 XMLComment* c0 = e0->ToComment();
568 XMLComment* c1 = e1->ToComment();
569
570 XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
571 XMLTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
572 }
573
574 {
575 XMLDocument xml;
576 xml.Parse( "<Parent>"
577 "<child1 att=''/>"
578 "<!-- With this comment, child2 will not be parsed! -->"
579 "<child2 att=''/>"
580 "</Parent>" );
581 xml.Print();
582
583 int count = 0;
584
585 for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild();
586 ele;
587 ele = ele->NextSibling() )
588 {
589 ++count;
590 }
591
592 XMLTest( "Comments iterate correctly.", 3, count );
593 }
594
595 {
596 // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
597 unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
598 buf[60] = 239;
599 buf[61] = 0;
600
601 XMLDocument doc;
602 doc.Parse( (const char*)buf);
603 }
604
605
606 {
607 // bug 1827248 Error while parsing a little bit malformed file
608 // Actually not malformed - should work.
609 XMLDocument xml;
610 xml.Parse( "<attributelist> </attributelist >" );
611 XMLTest( "Handle end tag whitespace", false, xml.Error() );
612 }
613
614 {
615 // This one must not result in an infinite loop
616 XMLDocument xml;
617 xml.Parse( "<infinite>loop" );
618 XMLTest( "Infinite loop test.", true, true );
619 }
620#endif
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800621
622 #if defined( _MSC_VER )
Lee Thomason1ff38e02012-02-14 18:18:16 -0800623 _CrtMemCheckpoint( &endMemState );
624 //_CrtMemDumpStatistics( &endMemState );
625
626 _CrtMemState diffMemState;
627 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
628 _CrtMemDumpStatistics( &diffMemState );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800629 //printf( "new total=%d\n", gNewTotal );
Lee Thomason1ff38e02012-02-14 18:18:16 -0800630 #endif
631
632 printf ("\nPass %d, Fail %d\n", gPass, gFail);
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800633 return 0;
Lee Thomason (grinliz)9b093cc2012-02-25 21:30:18 -0800634}