155 Commits
4.0.0 ... 5.0.1

Author SHA1 Message Date
Lee Thomason
37bc3aca42 upping the version to 5.0.1 to fix release vs. source problem 2017-06-26 16:56:16 -07:00
Lee Thomason
8c9e3133c4 remove error string inline. hopefully helps with odd linking issues 2017-06-26 16:55:01 -07:00
Lee Thomason
563ee82093 Merge pull request #571 from hyperair/cmake-add-test
Use CTest to add xmltest as a testcase so `make test` works
2017-06-26 16:40:06 -07:00
Lee Thomason
4ee9ebdfd2 Merge pull request #570 from jasjuang/master
fix issue #516
2017-06-26 16:37:42 -07:00
Lee Thomason
a4f48c1167 Merge pull request #572 from Dmitry-Me/swapFoundAndExpected
"Found" and "expected" were swapped in some tests
2017-06-26 16:37:21 -07:00
Dmitry-Me
9832a5f05d "Found" and "expected" were swapped in some tests 2017-06-23 18:29:16 +03:00
Chow Loong Jin
48d45b29a9 Use make test in travis.yml 2017-06-22 01:20:55 +08:00
Chow Loong Jin
5381145957 Use CTest to add xmltest as a testcase so make test works 2017-06-22 01:14:07 +08:00
jasjuang
a5ab98a582 fix issue #516 2017-06-20 17:25:42 -07:00
Lee Thomason
369f306b37 Merge branch 'master' of github.com:leethomason/tinyxml2 2017-06-20 09:18:54 -07:00
Lee Thomason
8bba8b41d6 mark unused enums 2017-06-20 09:18:41 -07:00
Lee Thomason
3f169ac424 Merge pull request #568 from Dmitry-Me/checkParsingErrorEarlier
Test parsing result as early as possible
2017-06-20 09:17:21 -07:00
Lee Thomason
86be0cdfe5 Merge pull request #566 from redagito/master
CMake fix for static library only build
2017-06-20 09:08:39 -07:00
Dmitry-Me
aea64c4b75 Test parsing result as early as possible 2017-06-20 18:20:15 +03:00
Robert J
dfcf5488ea CMake fix for static library only build 2017-06-20 13:41:17 +02:00
Lee Thomason
9201bb96d3 Merge pull request #563 from Dmitry-Me/betterParameterNameInClone
Better parameter name
2017-06-19 14:23:39 -07:00
Dmitry-Me
3f63f21cf5 Better parameter name 2017-06-19 18:25:19 +03:00
Lee Thomason
9e2d29b373 weird compile issues 2017-06-16 09:51:11 -07:00
Lee Thomason
82bb074b49 tweak test 2017-06-16 09:48:20 -07:00
Lee Thomason
224ef775c6 add test case 2017-06-16 09:45:26 -07:00
Lee Thomason
8a763619ac fix incorrect factoring 2017-06-16 09:30:16 -07:00
Lee Thomason
bc527554e8 Merge pull request #558 from leethomason/clone
Support clone (deep copy) of XMLDocument and XMLNode
2017-06-15 12:01:48 -07:00
Lee Thomason
5cfb946953 Merge pull request #562 from Dmitry-Me/testMemoryLeaksInDebugHeap
Programmatically check no leaks are reported in the VC++ debug heap
2017-06-15 10:30:30 -07:00
Lee Thomason
275067a91f Merge pull request #561 from Dmitry-Me/unlinkedElementsAssertions
Unlinked nodes assertions
2017-06-15 10:29:07 -07:00
Dmitry-Me
ed78570c66 Programmatically check no leaks are reported in the VC++ debug heap 2017-06-15 13:39:53 +03:00
Dmitry-Me
c2f677b05e Unlinked nodes assertions 2017-06-15 12:44:27 +03:00
Lee Thomason
1346a174ae tweak comments. fix copy to self case. 2017-06-14 15:14:19 -07:00
Lee Thomason
1bbc66b193 Merge branch 'master' into clone 2017-06-14 15:10:37 -07:00
Lee Thomason
e84f68a68a Merge branch 'memleak2' 2017-06-14 15:03:32 -07:00
Lee Thomason
b754ddf0fb address feedback from review 2017-06-14 15:02:38 -07:00
Lee Thomason
7ce75bc2bb Merge pull request #557 from jasjuang/master
Resolve issue #526
2017-06-14 14:50:53 -07:00
Lee Thomason
816d3fa0cd Fix string leaking (and destructors not getting called) when there are XMLNodes that aren't in the document tree 2017-06-05 14:35:55 -07:00
Lee Thomason
53858b4490 minor formatting fix and very strange memory tracker missing 2017-06-01 19:09:16 -07:00
Lee Thomason
ced18c05b9 missing var?? 2017-06-01 18:50:12 -07:00
Lee Thomason
a30f8bd136 Merge remote-tracking branch 'origin/master' into clone 2017-06-01 18:46:53 -07:00
Lee Thomason
b29f556ab0 comment 2017-06-01 18:45:32 -07:00
Lee Thomason
7085f00e40 deep copy and clone 2017-06-01 18:09:43 -07:00
jasjuang
f66441e3e7 add in support for cmake export, manual Findtinyxml2.cmake is no longer needed 2017-06-01 17:25:30 -07:00
Lee Thomason
33a1f8bd6c Merge pull request #552 from Dmitry-Me/ensureNoOverrunBeforeCopy
Ensure no overrun before copying
2017-05-18 21:13:48 -07:00
Lee Thomason
7538286750 Merge pull request #535 from jnguyen75/build-tests-option
Added BUILD_TESTS option to enable/disable xmltest
2017-05-18 20:57:41 -07:00
Dmitry-Me
243ddf5304 Ensure no overrun before copying 2017-05-18 17:27:14 +03:00
Jimmy Nguyen
105f32f64d Merge remote-tracking branch 'origin/master' into build-tests-option 2017-05-11 16:19:30 -07:00
Lee Thomason
174a5df3a3 Merge pull request #551 from eco/patch-1
Add "d" library suffix for debug builds
2017-05-05 19:55:08 -07:00
Brad Anderson
9333cfd394 Add "d" library suffix for debug builds 2017-05-04 12:25:56 -06:00
Lee Thomason
7b40ce1942 Merge pull request #534 from jnguyen75/ref-test-resources
Refactor test resources: Use CMake to replace mkdir()
2017-04-28 11:21:39 -07:00
Lee Thomason
b840b7e673 Merge pull request #547 from Dmitry-Me/clarifyVariableNames
Clarify variable names
2017-04-12 10:22:34 -07:00
Dmitry-Me
10b8ecc99b Clarify variable names 2017-04-12 17:57:44 +03:00
Lee Thomason
2b0453f43e Merge pull request #545 from Dmitry-Me/fullyUseEnum
Fully use enum
2017-04-06 13:27:29 -07:00
Dmitry-Me
e503563f47 Fully use enum 2017-04-05 18:02:40 +03:00
Lee Thomason
fc05f63575 Merge pull request #543 from Dmitry-Me/pointerAssertInShallowEqual
Pointer assertion
2017-03-22 14:36:32 -07:00
Dmitry-Me
ba68a3aea6 Pointer assertion 2017-03-21 11:39:48 +03:00
Lee Thomason
395ea09f83 Merge pull request #538 from Dmitry-Me/suppressC6011
Suppress C6011 code analysis false positive warning
2017-03-06 12:49:35 -08:00
Lee Thomason
71e2c08a7e Merge pull request #537 from Dmitry-Me/clearerMemberName
Clearer variable name
2017-03-06 12:48:33 -08:00
Dmitry-Me
7221b49fea Suppress C6011 code analysis false positive warning 2017-03-03 15:45:51 +03:00
Dmitry-Me
ae8a82a734 Clearer variable name 2017-03-03 15:40:32 +03:00
Lee Thomason
92c0ef327f Merge pull request #527 from Dmitry-Me/reuseNodesCreationCode
Extract and reuse nodes creation code
2017-03-01 13:15:52 -08:00
Dmitry-Me
2aebfb7123 Extract and reuse nodes creation code 2017-02-27 15:53:40 +03:00
Jimmy Nguyen
1e0b4e6b8a Use generator expression to specify target output directory for resources directory 2017-02-21 12:31:23 -08:00
Jimmy Nguyen
7f2ce0dc0e Updated Windows build script to change directory instead of copying files to run xmltest 2017-02-21 12:27:59 -08:00
Jimmy Nguyen
6bf64fb149 Use CMake to create resources/out directory 2017-02-21 12:00:38 -08:00
Jimmy Nguyen
47c7d70064 Added BUILD_TESTS option to enable/disable building of xmltest 2017-02-21 11:29:24 -08:00
Lee Thomason
b37cb42b78 Merge pull request #513 from leethomason/bool-write
Bool serialization.
2017-02-17 12:39:06 -08:00
Lee Thomason
0f42e24c47 Merge pull request #529 from Winestone/master
Fix typo in CMakeLists.txt
2017-02-14 11:24:51 -08:00
Jimmy Nguyen
969b8c2234 Replaced DATA_COPY target with post build command to copy the resources directory 2017-02-13 23:40:16 -08:00
Jimmy Nguyen
5277134efa Removed empty install() command 2017-02-13 23:24:38 -08:00
Winestone
4a07484e47 Fix typo in CMakeLists.txt 2017-02-11 23:04:14 +11:00
Lee Thomason
962732fd3e Merge pull request #520 from Dmitry-Me/initMemberVars2
Initialize member variable
2017-02-05 15:56:13 -08:00
Dmitry-Me
d120d64b86 Initialize member variable 2017-01-27 18:35:02 +03:00
Lee Thomason
1f5ab7cd0b Merge pull request #517 from Dmitry-Me/initMemberVars
Initialize member variables
2017-01-24 10:38:49 -08:00
Dmitry-Me
f89bd3ef68 Initialize member variables 2017-01-18 18:33:55 +03:00
Lee Thomason
c5c99c2ba0 tweaks to bool serialization 2016-12-29 11:19:17 -08:00
Lee Thomason
f458d265c1 fix const. hopefully. 2016-12-26 22:47:25 -08:00
Lee Thomason
ce667c9233 ability to set bool write values 2016-12-26 16:45:30 -08:00
Lee Thomason
5b733ff481 Merge pull request #504 from Dmitry-Me/ensureLinkPointersAreNotOverwritten
Ensure existing attributes are not leaked on attribute insertion
2016-12-24 07:39:17 -08:00
Lee Thomason
c3a19156ff Merge pull request #510 from leethomason/kezenator-line-numbering
Kezenator line numbering
2016-12-24 07:38:43 -08:00
Lee Thomason
e90e901041 tweaks, clarification to line numbers 2016-12-24 07:34:39 -08:00
Lee Thomason
002713856b Merge remote-tracking branch 'origin/master' into kezenator-line-numbering 2016-12-24 07:27:40 -08:00
Lee Thomason
855a66c0ff Merge pull request #509 from leethomason/fix-win-dll-build
Fix windows dll build/run
2016-12-24 07:27:25 -08:00
Lee Thomason
ef7fe0fd98 fix windows dll build/run 2016-12-24 07:07:56 -08:00
Dmitry-Me
34a3f8e34d Ensure existing attributes are not leaked on attribute insertion 2016-12-19 12:05:21 +03:00
kezenator
19d8ea836f CodeReview Fix: GetLineNum()? 2016-11-29 19:50:27 +10:00
kezenator
e353181a46 CodeReview Fix: initialLineNum? Something a little more descriptive? 2016-11-29 19:49:07 +10:00
kezenator
e3d44159e3 CodeReview Fix: The initializer syntax isn't used. Should be 'int unusedLineNum = 0` 2016-11-29 19:47:55 +10:00
kezenator
4f756161d0 CodeReview Fix: The non-const reference syntax isn't used in the codebase. Should be a pointer. 2016-11-29 19:46:27 +10:00
kezenator
2489afcc61 Merge branch 'master' of https://github.com/leethomason/tinyxml2 2016-11-29 19:33:44 +10:00
kezenator
a43ff7210e Removed line numbering support as an advantage of TinyXML-1.
Added error reporting system that discusses the support for line number information.
2016-11-26 17:33:12 +10:00
kezenator
ec6941503c Added line number reporting to parse errors and to all nodes and attributes for parsed documents. 2016-11-26 17:21:43 +10:00
Lee Thomason
156bc1b99f Merge pull request #502 from Dmitry-Me/reuseClearError
Reuse code for error clearing
2016-11-25 22:06:11 -08:00
Lee Thomason
5bbb6fb052 Merge pull request #500 from Dmitry-Me/reuseAttributeCreation
Reuse attribute creation code
2016-11-25 22:05:34 -08:00
kezenator
5a70071241 Added static method to convert arbitrary ErrorID to a string.
Updated tests to print ErrorID and bool values as strings.
2016-11-26 13:54:42 +10:00
Dmitry-Me
0d2cef0cba Reuse code for error clearing 2016-11-25 18:39:52 +03:00
Dmitry-Me
a60caa28cc Reuse attribute creation code 2016-11-22 18:28:08 +03:00
Lee Thomason
f80d78d938 Merge pull request #499 from Dmitry-Me/unifyNullComparisons
Unify null pointer checks
2016-11-17 14:43:55 -08:00
Dmitry-Me
ebb1660c2f Unify null pointer checks 2016-11-16 17:22:45 +03:00
Lee Thomason
7de0b6dd8c Merge pull request #493 from leethomason/jwittner
Friendly API for attribute query.
2016-11-15 14:09:03 -08:00
Lee Thomason
d04f21cab8 Merge pull request #496 from Dmitry-Me/detectDeclarationPlacement
Declarations should occur before anything else
2016-11-15 14:08:04 -08:00
Dmitry-Me
446c3bcae3 Declarations should occur before anything else 2016-11-11 10:34:56 +03:00
Lee Thomason
cd47f8e0d3 Merge pull request #495 from Dmitry-Me/pointerAssertionAfterIdentify
Pointer post-assertion
2016-11-10 14:36:10 -08:00
Dmitry-Me
4336431272 Pointer post-assertion 2016-11-07 18:48:50 +03:00
Lee Thomason
13cbc9a708 add test files. fix doc. 2016-10-27 14:55:07 -07:00
Lee Thomason
c9a6102bf1 Merge branch 'master' of git://github.com/jwittner/tinyxml2 into jwittner-master 2016-10-27 14:33:52 -07:00
Lee Thomason
6bbcda0215 Merge pull request #490 from Dmitry-Me/avoidCastToSigned
Avoid cast to signed integer type
2016-10-17 15:34:20 -07:00
Lee Thomason
15ad07170d Merge pull request #489 from Armagetron/master
Use correct file pointer
2016-10-17 15:33:57 -07:00
Lee Thomason
ed2627e5a7 Merge pull request #487 from jwittner/dev/slnFixes
Fixes for Visual Studio builds and gitignore output
2016-10-17 15:33:26 -07:00
Dmitry-Me
c5f1e7ce6e Avoid cast to signed integer type 2016-10-14 10:33:02 +03:00
Armagetron
3c21d6fbb7 Use correct file pointer 2016-10-13 13:31:23 +02:00
Lee Thomason
f6106bec9a Merge pull request #488 from Dmitry-Me/reuseElementWithNameCheck
Reuse "is element with name" check
2016-10-12 15:23:39 -07:00
Dmitry-Me
ecb9b07476 Reuse "is element with name" check 2016-10-12 16:44:59 +03:00
Josh Wittner
edb3261c51 Ignore SLn output dirs, VC files 2016-10-11 19:04:15 -07:00
Josh Wittner
01f6cca9e1 Standardize output directory - fixes conflicts 2016-10-11 19:03:10 -07:00
Josh Wittner
513e69ba68 Merge branch 'master' of https://github.com/leethomason/tinyxml2 2016-10-11 19:00:53 -07:00
Josh Wittner
cf3dd09b08 Move implementations to cpp 2016-10-11 18:57:17 -07:00
Lee Thomason
e8157ff9ae Merge pull request #484 from kainjow/patch-2
Fix warning on PowerPC
2016-10-11 13:52:45 -07:00
Lee Thomason
b2f4dc2a7b Merge pull request #483 from kainjow/patch-1
Fix typo
2016-10-11 13:45:35 -07:00
Lee Thomason
0d3de1edbe Merge pull request #482 from Dmitry-Me/stringEqualAssertions
Assertions in string comparison
2016-10-11 13:11:06 -07:00
Kevin Wojniak
318252a973 Fix warning on PowerPC
GCC 5+ will generate "error: comparison is always true due to limited range of data type" when -Wextra is used because PowerPC by default uses unsigned char, so it can never be less than 0.
2016-10-07 10:37:02 -07:00
Kevin Wojniak
3c97724d0e Fix typo 2016-10-06 16:05:59 -07:00
Dmitry-Me
21f996960d Assertions in string comparison 2016-10-03 13:01:57 +03:00
Lee Thomason
f00c179eba Merge pull request #480 from kurylo/fix/2016-09-29-cmake-warning
Fix cmake warnings on new cmake versions.
2016-10-02 21:24:49 -07:00
Lee Thomason
7fcf31b2c3 Merge pull request #477 from bejado/XML_NO_ERROR_Comments
Update comments to reflect single successful return type
2016-10-02 21:22:42 -07:00
Lee Thomason
6f1ad6153e Merge pull request #471 from Dmitry-Me/loopInvariantAssertions
Loop invariant pointer assertions
2016-10-02 21:21:38 -07:00
Łukasz Kuryło
aad61870a9 Fix cmake warnings on new cmake versions. 2016-09-29 18:59:07 +02:00
Benjamin Doherty
3b9cf99916 Update comments to reflect single successful return type 2016-09-23 18:42:23 -06:00
Lee Thomason
e9b547a9ee Merge pull request #475 from Dmitry-Me/splitAccessAndAdjustment
Split access and pointer adjustment
2016-09-14 10:31:10 -07:00
Josh Wittner
3a621f5b6e Added default values TypeText accessors 2016-09-12 19:17:54 -07:00
Dmitry-Me
fed511276f Split access and pointer adjustment 2016-09-06 18:08:55 +03:00
Lee Thomason
584af57086 fix error string memory errors 2016-09-05 14:14:16 -07:00
Lee Thomason
2e14517c89 Merge pull request #474 from Dmitry-Me/unifyIncDecOps
Unify increments and decrements
2016-09-05 13:52:58 -07:00
Lee Thomason
24694e9519 Merge pull request #473 from Dmitry-Me/preferConstAccess
Use const where const is enough
2016-09-05 13:52:22 -07:00
Lee Thomason
0d667f8fef Merge pull request #472 from Dmitry-Me/pointerAssertionsStrPairSet
Pointer assertions for substring
2016-09-05 13:51:59 -07:00
Dmitry-Me
3161a33c86 Unify increments and decrements 2016-09-02 16:58:06 +03:00
Dmitry-Me
2449582eaf Use const where const is enough 2016-09-02 16:53:32 +03:00
Dmitry-Me
6fc38ec7cc Pointer assertions for substring 2016-09-01 17:59:44 +03:00
Dmitry-Me
f9f3c3e85c Loop invariant pointer assertions 2016-08-30 15:51:55 +03:00
Lee Thomason
4fe8c102da Merge pull request #469 from Trebgarta/master
Bool true/false rather than 0/1 : #399
2016-08-28 17:21:04 -07:00
Lee Thomason
a369d4b614 Merge pull request #468 from Dmitry-Me/reuseDeleteChild
Reuse DeleteChild()
2016-08-28 17:13:28 -07:00
Doruk Turak
1f212f3ab0 Bool-related tests modified to pass 2016-08-28 20:54:17 +02:00
Doruk Turak
de45d04711 SetAttribute: true/false rather 1/0 2016-08-28 20:47:08 +02:00
Dmitry-Me
9cb4eca596 Reuse DeleteChild() 2016-08-18 18:10:59 +03:00
Lee Thomason
0bb5901961 Merge pull request #466 from Dmitry-Me/makeCommentMoreConcise
Make comment more concise
2016-08-11 07:34:16 -07:00
Lee Thomason
9faf14df53 Merge pull request #465 from Dmitry-Me/unifyNodeDeletion
Unify node deletion
2016-08-11 07:33:53 -07:00
Lee Thomason
cb6461ca9c Merge pull request #464 from mwoehlke-kitware/elf-visibility
ELF visibility
2016-08-11 07:32:50 -07:00
Lee Thomason
c7805c541c Merge pull request #463 from Dmitry-Me/clarifyMemoryPoolParts
Clarify "block" and "chunk"
2016-08-11 07:28:08 -07:00
Dmitry-Me
caa72a641e Make comment more concise 2016-08-10 17:34:34 +03:00
Dmitry-Me
4de7abb573 Unify node deletion 2016-08-10 17:30:02 +03:00
Matthew Woehlke
8170bdc693 Build with hidden symbols by default
Turn on options to tell CMake to use -fvisibility=hidden by default (on
applicable platforms). This has some optimization benefits, and more
closely mirrors the Windows behavior of only exporting symbols marked
for export, which can help catch errors doing so on non-Windows
platforms.

This requires CMake 2.8.12 to be effective. (Otherwise, the logic will
simply have no effect.)
2016-08-09 13:21:06 -04:00
Matthew Woehlke
a8e7ea7fb0 Set ELF visibility
Set symbol visibility to "default" on non-Windows platforms. This allows
building with -fvisibility=hidden, which has various advantages, and
which some projects will almost certainly want to do.
2016-08-09 13:16:26 -04:00
Dmitry-Me
88145b8ae6 Clarify "block" and "chunk" 2016-08-09 17:59:31 +03:00
Lee Thomason
75c8f40640 Merge pull request #459 from Elbrasch/master
Added void XMLPrinter::PushText( int64_t value ), which was declared …
2016-08-05 13:10:16 -07:00
Lee Thomason
1043f6feed Merge pull request #460 from Dmitry-Me/pointerAssertion
Pointer assertion for contract clarity
2016-08-05 13:09:25 -07:00
Dmitry-Me
db02b21bc5 Pointer assertion for contract clarity 2016-08-04 17:16:05 +03:00
Stefan Asbeck
e1a82c1a50 Added void XMLPrinter::PushText( int64_t value ), which was declared but not implemented. 2016-08-04 09:12:45 +02:00
Lee Thomason
74d44acb17 fix compile issues on clang 2016-07-17 22:57:36 -07:00
Lee Thomason
c9445466de fix permissive casting. 2016-07-17 22:53:48 -07:00
Lee Thomason
5bf60e9dc6 try to fix the lld issue 2016-07-17 22:49:40 -07:00
11 changed files with 1121 additions and 425 deletions

4
.gitignore vendored
View File

@@ -5,6 +5,8 @@ ipch/
resources/out/
tinyxml2/tinyxml2-cbp/bin/
tinyxml2/tinyxml2-cbp/obj/
tinyxml2/bin/
tinyxml2/temp/
*.sdf
*.suo
*.opensdf
@@ -12,3 +14,5 @@ tinyxml2/tinyxml2-cbp/obj/
*.depend
*.layout
*.o
*.vc.db
*.vc.opendb

View File

@@ -12,4 +12,4 @@ before_script: cmake .
script:
- make -j3
- ./xmltest
- make test

View File

@@ -7,9 +7,13 @@ IF(BIICODE)
ENDIF(BIICODE)
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
cmake_policy(VERSION 2.6)
if(POLICY CMP0063)
cmake_policy(SET CMP0063 OLD)
endif()
project(tinyxml2)
include(GNUInstallDirs)
include(CTest)
#enable_testing()
#CMAKE_BUILD_TOOL
@@ -17,52 +21,32 @@ include(GNUInstallDirs)
################################
# set lib version here
set(GENERIC_LIB_VERSION "4.0.0")
set(GENERIC_LIB_SOVERSION "4")
################################
# Add common source
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/.")
################################
# Add custom target to copy all data
set(TARGET_DATA_COPY DATA_COPY)
set(DATA_COPY_FILES)
if(NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
foreach(data dream.xml empty.xml utf8test.xml utf8testverify.xml)
set(DATA_COPY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/resources/${data})
set(DATA_COPY_DEST ${CMAKE_CURRENT_BINARY_DIR}/resources/${data})
add_custom_command(
OUTPUT ${DATA_COPY_DEST}
COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${DATA_COPY_SRC} ${DATA_COPY_DEST}
DEPENDS ${DATA_COPY_SRC})
list(APPEND DATA_COPY_FILES ${DATA_COPY_DEST})
endforeach(data)
endif(NOT ${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
add_custom_target(${TARGET_DATA_COPY} DEPENDS ${DATA_COPY_FILES})
set(GENERIC_LIB_VERSION "5.0.1")
set(GENERIC_LIB_SOVERSION "5")
################################
# Add definitions
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
################################
# Add targets
# By Default shared libray is being built
# To build static libs also - Do cmake . -DBUILD_STATIC_LIBS:BOOL=ON
# User can choose not to build shared library by using cmake -BUILD_SHARED_LIBS:BOOL:OFF
# User can choose not to build shared library by using cmake -DBUILD_SHARED_LIBS:BOOL=OFF
# To build only static libs use cmake . -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_STATIC_LIBS:BOOL=ON
# To build the tests, use cmake . -DBUILD_TESTS:BOOL=ON
# To disable the building of the tests, use cmake . -DBUILD_TESTS:BOOL=OFF
option(BUILD_SHARED_LIBS "build as shared library" ON)
option(BUILD_STATIC_LIBS "build as static library" OFF)
option(BUILD_TESTS "build xmltest (deprecated: Use BUILD_TESTING)" ON)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# to distinguish between debug and release lib
set(CMAKE_DEBUG_POSTFIX "d")
if(BUILD_SHARED_LIBS)
add_library(tinyxml2 SHARED tinyxml2.cpp tinyxml2.h)
@@ -72,11 +56,29 @@ set_target_properties(tinyxml2 PROPERTIES
VERSION "${GENERIC_LIB_VERSION}"
SOVERSION "${GENERIC_LIB_SOVERSION}")
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
target_include_directories(tinyxml2 INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.")
target_include_directories(tinyxml2 PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
if(MSVC)
target_compile_definitions(tinyxml2 PUBLIC -D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
else()
include_directories(${PROJECT_SOURCE_DIR})
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
endif()
# export targets for find_package config mode
export(TARGETS tinyxml2
FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
install(TARGETS tinyxml2
EXPORT ${CMAKE_PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
@@ -90,27 +92,54 @@ set_target_properties(tinyxml2_static PROPERTIES
SOVERSION "${GENERIC_LIB_SOVERSION}")
set_target_properties( tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2 )
target_compile_definitions(tinyxml2_static PUBLIC -D_CRT_SECURE_NO_WARNINGS)
if(DEFINED CMAKE_VERSION AND NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.11")
target_include_directories(tinyxml2_static INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/.")
target_include_directories(tinyxml2_static PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>)
if(MSVC)
target_compile_definitions(tinyxml2_static PUBLIC -D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
else()
include_directories(${PROJECT_SOURCE_DIR})
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif(MSVC)
endif()
# export targets for find_package config mode
export(TARGETS tinyxml2_static
FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
install(TARGETS tinyxml2_static
EXPORT ${CMAKE_PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
add_executable(xmltest xmltest.cpp)
if(BUILD_SHARED_LIBS)
add_dependencies(xmltest tinyxml2)
add_dependencies(xmltest ${TARGET_DATA_COPY})
target_link_libraries(xmltest tinyxml2)
else(BUILD_STATIC_LIBS)
add_dependencies(xmltest tinyxml2_static)
add_dependencies(xmltest ${TARGET_DATA_COPY})
target_link_libraries(xmltest tinyxml2_static)
if(BUILD_TESTING AND BUILD_TESTS)
add_executable(xmltest xmltest.cpp)
if(BUILD_SHARED_LIBS)
add_dependencies(xmltest tinyxml2)
target_link_libraries(xmltest tinyxml2)
else(BUILD_STATIC_LIBS)
add_dependencies(xmltest tinyxml2_static)
target_link_libraries(xmltest tinyxml2_static)
endif()
# Copy test resources and create test output directory
add_custom_command(TARGET xmltest POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/resources $<TARGET_FILE_DIR:xmltest>/resources
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:xmltest>/resources/out
COMMENT "Configuring xmltest resources directory: ${CMAKE_BINARY_DIR}/resources"
)
add_test(NAME xmltest COMMAND xmltest)
endif()
install(TARGETS DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES tinyxml2.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
@@ -124,13 +153,24 @@ endforeach()
configure_file(tinyxml2.pc.in tinyxml2.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/tinyxml2.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
#add_test(xmltest ${SAMPLE_NAME} COMMAND $<TARGET_FILE:${SAMPLE_NAME}>)
# uninstall target
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
file(WRITE
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
"include(\${CMAKE_CURRENT_LIST_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)\n")
install(FILES
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
install(EXPORT ${CMAKE_PROJECT_NAME}Targets
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})

View File

@@ -3,5 +3,5 @@ before_build:
build_script:
- msbuild tinyxml2.sln /m /p:Configuration=Release /t:ALL_BUILD
- copy Release\xmltest.exe .\ && copy Release\tinyxml2.dll .\
- cd Release
- xmltest.exe

2
dox
View File

@@ -38,7 +38,7 @@ PROJECT_NAME = "TinyXML-2"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 4.0.0
PROJECT_NUMBER = 5.0.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -88,9 +88,8 @@ Advantages of TinyXML-2
Advantages of TinyXML-1
1. Can report the location of parsing errors.
2. Support for some C++ STL conventions: streams and strings
3. Very mature and well debugged code base.
1. Support for some C++ STL conventions: streams and strings
2. Very mature and well debugged code base.
Features
--------
@@ -111,7 +110,7 @@ by the Document. When the Document is deleted, so are all the nodes it contains.
Microsoft has an excellent article on white space: http://msdn.microsoft.com/en-us/library/ms256097.aspx
By default, TinyXML-2 preserves white space in a (hopefully) sane way that is almost complient with the
By default, TinyXML-2 preserves white space in a (hopefully) sane way that is almost compliant with the
spec. (TinyXML-1 used a completely different model, much more similar to 'collapse', below.)
As a first step, all newlines / carriage-returns / line-feeds are normalized to a
@@ -157,6 +156,15 @@ However, you may also use COLLAPSE_WHITESPACE, which will:
Note that (currently) there is a performance impact for using COLLAPSE_WHITESPACE.
It essentially causes the XML to be parsed twice.
#### Error Reporting
TinyXML-2 reports the line number of any errors in an XML document that
cannot be parsed correctly. In addition, all nodes (elements, declarations,
text, comments etc.) and attributes have a line number recorded as they are parsed.
This allows an application that performs additional validation of the parsed
XML document (e.g. application-implemented DTD validation) to report
line number information in it's errors.
### Entities
TinyXML-2 recognizes the pre-defined "character entities", meaning special

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,7 @@ distribution.
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
*/
#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
#if defined( _DEBUG ) || defined (__DEBUG__)
# ifndef DEBUG
# define DEBUG
# endif
@@ -72,6 +72,8 @@ distribution.
# else
# define TINYXML2_LIB
# endif
#elif __GNUC__ >= 4
# define TINYXML2_LIB __attribute__((visibility("default")))
#else
# define TINYXML2_LIB
#endif
@@ -96,9 +98,9 @@ distribution.
/* Versioning, past 1.0.14:
http://semver.org/
*/
static const int TIXML2_MAJOR_VERSION = 4;
static const int TIXML2_MAJOR_VERSION = 5;
static const int TIXML2_MINOR_VERSION = 0;
static const int TIXML2_PATCH_VERSION = 0;
static const int TIXML2_PATCH_VERSION = 1;
namespace tinyxml2
{
@@ -125,18 +127,20 @@ public:
NEEDS_NEWLINE_NORMALIZATION = 0x02,
NEEDS_WHITESPACE_COLLAPSING = 0x04,
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
ATTRIBUTE_NAME = 0,
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
COMMENT = NEEDS_NEWLINE_NORMALIZATION
ATTRIBUTE_NAME = 0,
ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
COMMENT = NEEDS_NEWLINE_NORMALIZATION
};
StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {}
~StrPair();
void Set( char* start, char* end, int flags ) {
TIXMLASSERT( start );
TIXMLASSERT( end );
Reset();
_start = start;
_end = end;
@@ -156,13 +160,13 @@ public:
void SetStr( const char* str, int flags=0 );
char* ParseText( char* in, const char* endTag, int strFlags );
char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr );
char* ParseName( char* in );
void TransferTo( StrPair* other );
void Reset();
private:
void Reset();
void CollapseWhitespace();
enum {
@@ -207,7 +211,8 @@ public:
void Push( T t ) {
TIXMLASSERT( _size < INT_MAX );
EnsureCapacity( _size+1 );
_mem[_size++] = t;
_mem[_size] = t;
++_size;
}
T* PushArr( int count ) {
@@ -221,7 +226,8 @@ public:
T Pop() {
TIXMLASSERT( _size > 0 );
return _mem[--_size];
--_size;
return _mem[_size];
}
void PopArr( int count ) {
@@ -258,6 +264,13 @@ public:
return _allocated;
}
void SwapRemove(int i) {
TIXMLASSERT(i >= 0 && i < _size);
TIXMLASSERT(_size > 0);
_mem[i] = _mem[_size - 1];
--_size;
}
const T* Mem() const {
TIXMLASSERT( _mem );
return _mem;
@@ -278,6 +291,7 @@ private:
TIXMLASSERT( cap <= INT_MAX / 2 );
int newAllocated = cap * 2;
T* newMem = new T[newAllocated];
TIXMLASSERT( newAllocated >= _size );
memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
if ( _mem != _pool ) {
delete [] _mem;
@@ -315,7 +329,7 @@ public:
/*
Template child class to create pools of the correct type.
*/
template< int SIZE >
template< int ITEM_SIZE >
class MemPoolT : public MemPool
{
public:
@@ -338,7 +352,7 @@ public:
}
virtual int ItemSize() const {
return SIZE;
return ITEM_SIZE;
}
int CurrentAllocs() const {
return _currentAllocs;
@@ -350,21 +364,23 @@ public:
Block* block = new Block();
_blockPtrs.Push( block );
for( int i=0; i<COUNT-1; ++i ) {
block->chunk[i].next = &block->chunk[i+1];
Item* blockItems = block->items;
for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) {
blockItems[i].next = &(blockItems[i + 1]);
}
block->chunk[COUNT-1].next = 0;
_root = block->chunk;
blockItems[ITEMS_PER_BLOCK - 1].next = 0;
_root = blockItems;
}
void* result = _root;
Item* const result = _root;
TIXMLASSERT( result != 0 );
_root = _root->next;
++_currentAllocs;
if ( _currentAllocs > _maxAllocs ) {
_maxAllocs = _currentAllocs;
}
_nAllocs++;
_nUntracked++;
++_nAllocs;
++_nUntracked;
return result;
}
@@ -373,20 +389,21 @@ public:
return;
}
--_currentAllocs;
Chunk* chunk = static_cast<Chunk*>( mem );
Item* item = static_cast<Item*>( mem );
#ifdef DEBUG
memset( chunk, 0xfe, sizeof(Chunk) );
memset( item, 0xfe, sizeof( *item ) );
#endif
chunk->next = _root;
_root = chunk;
item->next = _root;
_root = item;
}
void Trace( const char* name ) {
printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
name, _maxAllocs, _maxAllocs*SIZE/1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size() );
name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs,
ITEM_SIZE, _nAllocs, _blockPtrs.Size() );
}
void SetTracked() {
_nUntracked--;
--_nUntracked;
}
int Untracked() const {
@@ -402,21 +419,23 @@ public:
// 16k: 5200
// 32k: 4300
// 64k: 4000 21000
enum { COUNT = (4*1024)/SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private
// Declared public because some compilers do not accept to use ITEMS_PER_BLOCK
// in private part if ITEMS_PER_BLOCK is private
enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE };
private:
MemPoolT( const MemPoolT& ); // not supported
void operator=( const MemPoolT& ); // not supported
union Chunk {
Chunk* next;
char mem[SIZE];
union Item {
Item* next;
char itemData[ITEM_SIZE];
};
struct Block {
Chunk chunk[COUNT];
Item items[ITEMS_PER_BLOCK];
};
DynArray< Block*, 10 > _blockPtrs;
Chunk* _root;
Item* _root;
int _currentAllocs;
int _nAllocs;
@@ -494,10 +513,10 @@ enum XMLError {
XML_ERROR_FILE_NOT_FOUND,
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
XML_ERROR_FILE_READ_ERROR,
XML_ERROR_ELEMENT_MISMATCH,
UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version
XML_ERROR_PARSING_ELEMENT,
XML_ERROR_PARSING_ATTRIBUTE,
XML_ERROR_IDENTIFYING_TAG,
UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version
XML_ERROR_PARSING_TEXT,
XML_ERROR_PARSING_CDATA,
XML_ERROR_PARSING_COMMENT,
@@ -516,19 +535,23 @@ enum XMLError {
/*
Utility functionality.
*/
class XMLUtil
class TINYXML2_LIB XMLUtil
{
public:
static const char* SkipWhiteSpace( const char* p ) {
static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) {
TIXMLASSERT( p );
while( IsWhiteSpace(*p) ) {
if (curLineNumPtr && *p == '\n') {
++(*curLineNumPtr);
}
++p;
}
TIXMLASSERT( p );
return p;
}
static char* SkipWhiteSpace( char* p ) {
return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p) ) );
static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) {
return const_cast<char*>( SkipWhiteSpace( const_cast<const char*>(p), curLineNumPtr ) );
}
// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
@@ -559,6 +582,9 @@ public:
if ( p == q ) {
return true;
}
TIXMLASSERT( p );
TIXMLASSERT( q );
TIXMLASSERT( nChar >= 0 );
return strncmp( p, q, nChar ) == 0;
}
@@ -587,6 +613,17 @@ public:
static bool ToFloat( const char* str, float* value );
static bool ToDouble( const char* str, double* value );
static bool ToInt64(const char* str, int64_t* value);
// Changes what is serialized for a boolean value.
// Default to "true" and "false". Shouldn't be changed
// unless you have a special testing or compatibility need.
// Be careful: static, global, & not thread safe.
// Be sure to set static const memory as parameters.
static void SetBoolSerialization(const char* writeTrue, const char* writeFalse);
private:
static const char* writeBoolTrue;
static const char* writeBoolFalse;
};
@@ -692,6 +729,9 @@ public:
*/
void SetValue( const char* val, bool staticMem=false );
/// Gets the line number the node is in, if the document was parsed from a file.
int GetLineNum() const { return _parseLineNum; }
/// Get the parent of this node on the DOM.
const XMLNode* Parent() const {
return _parent;
@@ -825,6 +865,21 @@ public:
*/
virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
/**
Make a copy of this node and all its children.
If the 'target' is null, then the nodes will
be allocated in the current document. If 'target'
is specified, the memory will be allocated is the
specified XMLDocument.
NOTE: This is probably not the correct tool to
copy a document, since XMLDocuments can have multiple
top level XMLNodes. You probably want to use
XMLDocument::DeepCopy()
*/
XMLNode* DeepClone( XMLDocument* target ) const;
/**
Test if 2 nodes are the same, but don't test children.
The 2 nodes do not need to be in the same Document.
@@ -875,11 +930,12 @@ protected:
XMLNode( XMLDocument* );
virtual ~XMLNode();
virtual char* ParseDeep( char*, StrPair* );
virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
XMLDocument* _document;
XMLNode* _parent;
mutable StrPair _value;
int _parseLineNum;
XMLNode* _firstChild;
XMLNode* _lastChild;
@@ -894,6 +950,7 @@ private:
void Unlink( XMLNode* child );
static void DeleteNode( XMLNode* node );
void InsertChildPreamble( XMLNode* insertThis ) const;
const XMLElement* ToElementWithName( const char* name ) const;
XMLNode( const XMLNode& ); // not supported
XMLNode& operator=( const XMLNode& ); // not supported
@@ -941,7 +998,7 @@ protected:
XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
virtual ~XMLText() {}
char* ParseDeep( char*, StrPair* endTag );
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private:
bool _isCData;
@@ -972,7 +1029,7 @@ protected:
XMLComment( XMLDocument* doc );
virtual ~XMLComment();
char* ParseDeep( char*, StrPair* endTag );
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
private:
XMLComment( const XMLComment& ); // not supported
@@ -1011,7 +1068,7 @@ protected:
XMLDeclaration( XMLDocument* doc );
virtual ~XMLDeclaration();
char* ParseDeep( char*, StrPair* endTag );
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private:
XMLDeclaration( const XMLDeclaration& ); // not supported
@@ -1046,7 +1103,7 @@ protected:
XMLUnknown( XMLDocument* doc );
virtual ~XMLUnknown();
char* ParseDeep( char*, StrPair* endTag );
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private:
XMLUnknown( const XMLUnknown& ); // not supported
@@ -1071,6 +1128,9 @@ public:
/// The value of the attribute.
const char* Value() const;
/// Gets the line number the attribute is in, if the document was parsed from a file.
int GetLineNum() const { return _parseLineNum; }
/// The next attribute in the list.
const XMLAttribute* Next() const {
return _next;
@@ -1118,7 +1178,7 @@ public:
}
/** QueryIntValue interprets the attribute as an integer, and returns the value
in the provided parameter. The function will return XML_NO_ERROR on success,
in the provided parameter. The function will return XML_SUCCESS on success,
and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
*/
XMLError QueryIntValue( int* value ) const;
@@ -1151,17 +1211,18 @@ public:
private:
enum { BUF_SIZE = 200 };
XMLAttribute() : _next( 0 ), _memPool( 0 ) {}
XMLAttribute() : _parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
virtual ~XMLAttribute() {}
XMLAttribute( const XMLAttribute& ); // not supported
void operator=( const XMLAttribute& ); // not supported
void SetName( const char* name );
char* ParseDeep( char* p, bool processEntities );
char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr );
mutable StrPair _name;
mutable StrPair _value;
int _parseLineNum;
XMLAttribute* _next;
MemPool* _memPool;
};
@@ -1218,51 +1279,25 @@ public:
const char* Attribute( const char* name, const char* value=0 ) const;
/** Given an attribute name, IntAttribute() returns the value
of the attribute interpreted as an integer. 0 will be
returned if there is an error. For a method with error
checking, see QueryIntAttribute()
of the attribute interpreted as an integer. The default
value will be returned if the attribute isn't present,
or if there is an error. (For a method with error
checking, see QueryIntAttribute()).
*/
int IntAttribute( const char* name ) const {
int i=0;
QueryIntAttribute( name, &i );
return i;
}
int IntAttribute(const char* name, int defaultValue = 0) const;
/// See IntAttribute()
unsigned UnsignedAttribute( const char* name ) const {
unsigned i=0;
QueryUnsignedAttribute( name, &i );
return i;
}
unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
/// See IntAttribute()
int64_t Int64Attribute(const char* name) const {
int64_t i = 0;
QueryInt64Attribute(name, &i);
return i;
}
int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
/// See IntAttribute()
bool BoolAttribute( const char* name ) const {
bool b=false;
QueryBoolAttribute( name, &b );
return b;
}
bool BoolAttribute(const char* name, bool defaultValue = false) const;
/// See IntAttribute()
double DoubleAttribute( const char* name ) const {
double d=0;
QueryDoubleAttribute( name, &d );
return d;
}
double DoubleAttribute(const char* name, double defaultValue = 0) const;
/// See IntAttribute()
float FloatAttribute( const char* name ) const {
float f=0;
QueryFloatAttribute( name, &f );
return f;
}
float FloatAttribute(const char* name, float defaultValue = 0) const;
/** Given an attribute name, QueryIntAttribute() returns
XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
can't be performed, or XML_NO_ATTRIBUTE if the attribute
doesn't exist. If successful, the result of the conversion
will be written to 'value'. If not successful, nothing will
@@ -1327,7 +1362,7 @@ public:
/** Given an attribute name, QueryAttribute() returns
XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
can't be performed, or XML_NO_ATTRIBUTE if the attribute
doesn't exist. It is overloaded for the primitive types,
and is a generally more convenient replacement of
@@ -1533,20 +1568,33 @@ public:
/// See QueryIntText()
XMLError QueryFloatText( float* fval ) const;
int IntText(int defaultValue = 0) const;
/// See QueryIntText()
unsigned UnsignedText(unsigned defaultValue = 0) const;
/// See QueryIntText()
int64_t Int64Text(int64_t defaultValue = 0) const;
/// See QueryIntText()
bool BoolText(bool defaultValue = false) const;
/// See QueryIntText()
double DoubleText(double defaultValue = 0) const;
/// See QueryIntText()
float FloatText(float defaultValue = 0) const;
// internal:
enum {
enum ElementClosingType {
OPEN, // <foo>
CLOSED, // <foo/>
CLOSING // </foo>
};
int ClosingType() const {
ElementClosingType ClosingType() const {
return _closingType;
}
virtual XMLNode* ShallowClone( XMLDocument* document ) const;
virtual bool ShallowEqual( const XMLNode* compare ) const;
protected:
char* ParseDeep( char* p, StrPair* endTag );
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
private:
XMLElement( XMLDocument* doc );
@@ -1559,11 +1607,12 @@ private:
}
XMLAttribute* FindOrCreateAttribute( const char* name );
//void LinkAttribute( XMLAttribute* attrib );
char* ParseAttributes( char* p );
char* ParseAttributes( char* p, int* curLineNumPtr );
static void DeleteAttribute( XMLAttribute* attribute );
XMLAttribute* CreateAttribute();
enum { BUF_SIZE = 200 };
int _closingType;
ElementClosingType _closingType;
// The attribute list is ordered; there is no 'lastAttribute'
// because the list needs to be scanned for dupes before adding
// a new attribute.
@@ -1587,7 +1636,7 @@ class TINYXML2_LIB XMLDocument : public XMLNode
friend class XMLElement;
public:
/// constructor
XMLDocument( bool processEntities = true, Whitespace = PRESERVE_WHITESPACE );
XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE );
~XMLDocument();
virtual XMLDocument* ToDocument() {
@@ -1601,7 +1650,7 @@ public:
/**
Parse an XML file from a character string.
Returns XML_NO_ERROR (0) on success, or
Returns XML_SUCCESS (0) on success, or
an errorID.
You may optionally pass in the 'nBytes', which is
@@ -1613,7 +1662,7 @@ public:
/**
Load an XML file from disk.
Returns XML_NO_ERROR (0) on success, or
Returns XML_SUCCESS (0) on success, or
an errorID.
*/
XMLError LoadFile( const char* filename );
@@ -1626,14 +1675,14 @@ public:
not text in order for TinyXML-2 to correctly
do newline normalization.
Returns XML_NO_ERROR (0) on success, or
Returns XML_SUCCESS (0) on success, or
an errorID.
*/
XMLError LoadFile( FILE* );
/**
Save the XML file to disk.
Returns XML_NO_ERROR (0) on success, or
Returns XML_SUCCESS (0) on success, or
an errorID.
*/
XMLError SaveFile( const char* filename, bool compact = false );
@@ -1642,7 +1691,7 @@ public:
Save the XML file to disk. You are responsible
for providing and closing the FILE*.
Returns XML_NO_ERROR (0) on success, or
Returns XML_SUCCESS (0) on success, or
an errorID.
*/
XMLError SaveFile( FILE* fp, bool compact = false );
@@ -1651,7 +1700,7 @@ public:
return _processEntities;
}
Whitespace WhitespaceMode() const {
return _whitespace;
return _whitespaceMode;
}
/**
@@ -1736,7 +1785,11 @@ public:
*/
void DeleteNode( XMLNode* node );
void SetError( XMLError error, const char* str1, const char* str2 );
void SetError( XMLError error, const char* str1, const char* str2, int lineNum );
void ClearError() {
SetError(XML_SUCCESS, 0, 0, 0);
}
/// Return true if there was an error parsing the document.
bool Error() const {
@@ -1747,14 +1800,18 @@ public:
return _errorID;
}
const char* ErrorName() const;
static const char* ErrorIDToName(XMLError errorID);
/// Return a possibly helpful diagnostic location or string.
const char* GetErrorStr1() const {
return _errorStr1;
}
const char* GetErrorStr1() const;
/// Return a possibly helpful secondary diagnostic location or string.
const char* GetErrorStr2() const {
return _errorStr2;
const char* GetErrorStr2() const;
/// Return the line where the error occured, or zero if unknown.
int GetErrorLineNum() const
{
return _errorLineNum;
}
/// If there is an error, print it to stdout.
void PrintError() const;
@@ -1762,9 +1819,21 @@ public:
/// Clear the document, resetting it to the initial state.
void Clear();
// internal
/**
Copies this document to a target document.
The target will be completely cleared before the copy.
If you want to copy a sub-tree, see XMLNode::DeepClone().
NOTE: that the 'target' must be non-null.
*/
void DeepCopy(XMLDocument* target);
// internal
char* Identify( char* p, XMLNode** node );
// internal
void MarkInUse(XMLNode*);
virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const {
return 0;
}
@@ -1776,13 +1845,22 @@ private:
XMLDocument( const XMLDocument& ); // not supported
void operator=( const XMLDocument& ); // not supported
bool _writeBOM;
bool _processEntities;
XMLError _errorID;
Whitespace _whitespace;
const char* _errorStr1;
const char* _errorStr2;
char* _charBuffer;
bool _writeBOM;
bool _processEntities;
XMLError _errorID;
Whitespace _whitespaceMode;
mutable StrPair _errorStr1;
mutable StrPair _errorStr2;
int _errorLineNum;
char* _charBuffer;
int _parseCurLineNum;
// Memory tracking does add some overhead.
// However, the code assumes that you don't
// have a bunch of unlinked nodes around.
// Therefore it takes less memory to track
// in the document vs. a linked list in the XMLNode,
// and the performance is the same.
DynArray<XMLNode*, 10> _unlinked;
MemPoolT< sizeof(XMLElement) > _elementPool;
MemPoolT< sizeof(XMLAttribute) > _attributePool;
@@ -1792,8 +1870,23 @@ private:
static const char* _errorNames[XML_ERROR_COUNT];
void Parse();
template<class NodeType, int PoolElementSize>
NodeType* CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool );
};
template<class NodeType, int PoolElementSize>
inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT<PoolElementSize>& pool )
{
TIXMLASSERT( sizeof( NodeType ) == PoolElementSize );
TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() );
NodeType* returnNode = new (pool.Alloc()) NodeType( this );
TIXMLASSERT( returnNode );
returnNode->_memPool = &pool;
_unlinked.Push(returnNode);
return returnNode;
}
/**
A XMLHandle is a class that wraps a node pointer with null checks; this is
@@ -1910,19 +2003,19 @@ public:
}
/// Safe cast to XMLElement. This can return null.
XMLElement* ToElement() {
return ( ( _node == 0 ) ? 0 : _node->ToElement() );
return ( _node ? _node->ToElement() : 0 );
}
/// Safe cast to XMLText. This can return null.
XMLText* ToText() {
return ( ( _node == 0 ) ? 0 : _node->ToText() );
return ( _node ? _node->ToText() : 0 );
}
/// Safe cast to XMLUnknown. This can return null.
XMLUnknown* ToUnknown() {
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
return ( _node ? _node->ToUnknown() : 0 );
}
/// Safe cast to XMLDeclaration. This can return null.
XMLDeclaration* ToDeclaration() {
return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
return ( _node ? _node->ToDeclaration() : 0 );
}
private:
@@ -1982,16 +2075,16 @@ public:
return _node;
}
const XMLElement* ToElement() const {
return ( ( _node == 0 ) ? 0 : _node->ToElement() );
return ( _node ? _node->ToElement() : 0 );
}
const XMLText* ToText() const {
return ( ( _node == 0 ) ? 0 : _node->ToText() );
return ( _node ? _node->ToText() : 0 );
}
const XMLUnknown* ToUnknown() const {
return ( ( _node == 0 ) ? 0 : _node->ToUnknown() );
return ( _node ? _node->ToUnknown() : 0 );
}
const XMLDeclaration* ToDeclaration() const {
return ( ( _node == 0 ) ? 0 : _node->ToDeclaration() );
return ( _node ? _node->ToDeclaration() : 0 );
}
private:
@@ -2125,6 +2218,7 @@ public:
void ClearBuffer() {
_buffer.Clear();
_buffer.Push(0);
_firstElement = true;
}
protected:

View File

@@ -136,47 +136,47 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'">
<IntDir>$(SolutionDir)$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<IntDir>$(SolutionDir)$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
<IntDir>$(SolutionDir)$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'">
<IntDir>$(SolutionDir)$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'">
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'">
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'">
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<ClCompile>

View File

@@ -141,35 +141,43 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Dll|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Lib|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Dll|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)bin\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(Platform)-$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)bin\$(ProjectName)\$(Platform)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)temp\$(ProjectName)\$(Platform)-$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Lib|Win32'">
<ClCompile>

View File

@@ -10,16 +10,11 @@
#include <ctime>
#if defined( _MSC_VER )
#include <direct.h> // _mkdir
#include <crtdbg.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
_CrtMemState startMemState;
_CrtMemState endMemState;
#elif defined(MINGW32) || defined(__MINGW32__)
#include <io.h> // mkdir
#else
#include <sys/stat.h> // mkdir
#endif
using namespace tinyxml2;
@@ -63,6 +58,15 @@ bool XMLTest (const char* testString, const char* expected, const char* found, b
return pass;
}
bool XMLTest(const char* testString, XMLError expected, XMLError found, bool echo = true, bool extraNL = false)
{
return XMLTest(testString, XMLDocument::ErrorIDToName(expected), XMLDocument::ErrorIDToName(found), echo, extraNL);
}
bool XMLTest(const char* testString, bool expected, bool found, bool echo = true, bool extraNL = false)
{
return XMLTest(testString, expected ? "true" : "false", found ? "true" : "false", echo, extraNL);
}
template< class T > bool XMLTest( const char* testString, T expected, T found, bool echo=true )
{
@@ -288,17 +292,10 @@ int main( int argc, const char ** argv )
_CrtMemCheckpoint( &startMemState );
// Enable MS Visual C++ debug heap memory leaks dump on exit
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
#endif
#if defined(_MSC_VER) || defined(MINGW32) || defined(__MINGW32__)
#if defined __MINGW64_VERSION_MAJOR && defined __MINGW64_VERSION_MINOR
//MINGW64: both 32 and 64-bit
mkdir( "resources/out/" );
#else
_mkdir( "resources/out/" );
#endif
#else
mkdir( "resources/out/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
{
int leaksOnStart = _CrtDumpMemoryLeaks();
XMLTest( "No leaks on start?", FALSE, leaksOnStart );
}
#endif
{
@@ -426,7 +423,7 @@ int main( int argc, const char ** argv )
XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
XMLTest( "Programmatic DOM", "& Text!",
doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
XMLTest("User data", 2, (int)comment->GetUserData());
XMLTest("User data", (void*)2 == comment->GetUserData(), true, false);
// And now deletion:
element->DeleteChild( sub[2] );
@@ -436,10 +433,12 @@ int main( int argc, const char ** argv )
element->LastChildElement()->DeleteAttribute( "attrib" );
XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
int value = 10;
int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
XMLTest( "Programmatic DOM", result, (int)XML_NO_ATTRIBUTE );
XMLTest( "Programmatic DOM", value, 10 );
int value1 = 10;
int value2 = doc->FirstChildElement()->LastChildElement()->IntAttribute( "attrib", 10 );
XMLError result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value1 );
XMLTest( "Programmatic DOM", XML_NO_ATTRIBUTE, result );
XMLTest( "Programmatic DOM", 10, value1 );
XMLTest( "Programmatic DOM", 10, value2 );
doc->Print();
@@ -451,7 +450,7 @@ int main( int argc, const char ** argv )
{
XMLPrinter streamer( 0, true );
doc->Print( &streamer );
XMLTest( "Compact mode", "<element><sub attrib=\"1\"/><sub/></element>", streamer.CStr(), false );
XMLTest( "Compact mode", "<element><sub attrib=\"true\"/><sub/></element>", streamer.CStr(), false );
}
doc->SaveFile( "./resources/out/pretty.xml" );
doc->SaveFile( "./resources/out/compact.xml", true );
@@ -500,7 +499,7 @@ int main( int argc, const char ** argv )
XMLDocument doc;
doc.Parse( error );
XMLTest( "Bad XML", doc.ErrorID(), XML_ERROR_PARSING_ATTRIBUTE );
XMLTest( "Bad XML", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() );
}
{
@@ -511,22 +510,31 @@ int main( int argc, const char ** argv )
XMLElement* ele = doc.FirstChildElement();
int iVal, result;
int iVal;
XMLError result;
double dVal;
result = ele->QueryDoubleAttribute( "attr0", &dVal );
XMLTest( "Query attribute: int as double", result, (int)XML_SUCCESS);
XMLTest( "Query attribute: int as double", (int)dVal, 1 );
XMLTest( "Query attribute: int as double", XML_SUCCESS, result);
XMLTest( "Query attribute: int as double", 1, (int)dVal );
XMLTest( "Query attribute: int as double", 1, (int)ele->DoubleAttribute("attr0"));
result = ele->QueryDoubleAttribute( "attr1", &dVal );
XMLTest( "Query attribute: double as double", result, (int)XML_SUCCESS);
XMLTest( "Query attribute: double as double", (int)dVal, 2 );
XMLTest( "Query attribute: double as double", XML_SUCCESS, result);
XMLTest( "Query attribute: double as double", 2.0, dVal );
XMLTest( "Query attribute: double as double", 2.0, ele->DoubleAttribute("attr1") );
result = ele->QueryIntAttribute( "attr1", &iVal );
XMLTest( "Query attribute: double as int", result, (int)XML_SUCCESS);
XMLTest( "Query attribute: double as int", iVal, 2 );
XMLTest( "Query attribute: double as int", XML_SUCCESS, result);
XMLTest( "Query attribute: double as int", 2, iVal );
result = ele->QueryIntAttribute( "attr2", &iVal );
XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE );
XMLTest( "Query attribute: not a number", XML_WRONG_ATTRIBUTE_TYPE, result );
XMLTest( "Query attribute: not a number", 4.0, ele->DoubleAttribute("attr2", 4.0) );
result = ele->QueryIntAttribute( "bar", &iVal );
XMLTest( "Query attribute: does not exist", result, (int)XML_NO_ATTRIBUTE );
XMLTest( "Query attribute: does not exist", XML_NO_ATTRIBUTE, result );
XMLTest( "Query attribute: does not exist", true, ele->BoolAttribute("bar", true) );
}
{
@@ -551,12 +559,14 @@ int main( int argc, const char ** argv )
ele->QueryAttribute( "int", &iVal2 );
ele->QueryAttribute( "double", &dVal2 );
XMLTest( "Attribute match test", ele->Attribute( "str", "strValue" ), "strValue" );
XMLTest( "Attribute match test", "strValue", ele->Attribute( "str", "strValue" ) );
XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
XMLTest( "Attribute round trip. int.", 1, iVal );
XMLTest( "Attribute round trip. double.", -1, (int)dVal );
XMLTest( "Alternate query", true, iVal == iVal2 );
XMLTest( "Alternate query", true, dVal == dVal2 );
XMLTest( "Alternate query", true, iVal == ele->IntAttribute("int") );
XMLTest( "Alternate query", true, dVal == ele->DoubleAttribute("double") );
}
{
@@ -679,7 +689,7 @@ int main( int argc, const char ** argv )
XMLTest( "SetText types", "1", element->GetText() );
element->SetText( true );
XMLTest( "SetText types", "1", element->GetText() ); // TODO: should be 'true'?
XMLTest( "SetText types", "true", element->GetText() );
element->SetText( 1.5f );
XMLTest( "SetText types", "1.5", element->GetText() );
@@ -702,6 +712,7 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: int", -100, v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: int", -100, v, true);
XMLTest("Attribute: int", -100, element->IntAttribute("attrib"), true);
}
{
element->SetAttribute("attrib", unsigned(100));
@@ -710,6 +721,7 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: unsigned", unsigned(100), v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: unsigned", unsigned(100), v, true);
XMLTest("Attribute: unsigned", unsigned(100), element->UnsignedAttribute("attrib"), true);
}
{
element->SetAttribute("attrib", BIG);
@@ -718,6 +730,7 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: int64_t", BIG, v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: int64_t", BIG, v, true);
XMLTest("Attribute: int64_t", BIG, element->Int64Attribute("attrib"), true);
}
{
element->SetAttribute("attrib", true);
@@ -726,6 +739,19 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: bool", true, v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: bool", true, v, true);
XMLTest("Attribute: bool", true, element->BoolAttribute("attrib"), true);
}
{
element->SetAttribute("attrib", true);
const char* result = element->Attribute("attrib");
XMLTest("Bool true is 'true'", "true", result);
XMLUtil::SetBoolSerialization("1", "0");
element->SetAttribute("attrib", true);
result = element->Attribute("attrib");
XMLTest("Bool true is '1'", "1", result);
XMLUtil::SetBoolSerialization(0, 0);
}
{
element->SetAttribute("attrib", 100.0);
@@ -734,6 +760,7 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: double", 100.0, v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: double", 100.0, v, true);
XMLTest("Attribute: double", 100.0, element->DoubleAttribute("attrib"), true);
}
{
element->SetAttribute("attrib", 100.0f);
@@ -742,6 +769,7 @@ int main( int argc, const char ** argv )
XMLTest("Attribute: float", 100.0f, v, true);
element->QueryAttribute("attrib", &v);
XMLTest("Attribute: float", 100.0f, v, true);
XMLTest("Attribute: float", 100.0f, element->FloatAttribute("attrib"), true);
}
{
element->SetText(BIG);
@@ -769,7 +797,7 @@ int main( int argc, const char ** argv )
{
XMLDocument doc;
doc.LoadFile("resources/printer.xml");
XMLTest("XMLPrinter Stream mode: load", doc.ErrorID(), XML_SUCCESS, true);
XMLTest("XMLPrinter Stream mode: load", XML_SUCCESS, doc.ErrorID(), true);
const XMLDocument& cdoc = doc;
@@ -802,8 +830,8 @@ int main( int argc, const char ** argv )
doc.Parse( str );
doc.Print();
XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
"I am > the rules!\n...since I make symbolic puns",
XMLTest( "CDATA parse.", "I am > the rules!\n...since I make symbolic puns",
doc.FirstChildElement()->FirstChild()->Value(),
false );
}
@@ -819,8 +847,9 @@ int main( int argc, const char ** argv )
doc.Parse( str );
doc.Print();
XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
XMLTest( "CDATA parse. [ tixml1:1480107 ]",
"<b>I am > the rules!</b>\n...since I make symbolic puns",
doc.FirstChildElement()->FirstChild()->Value(),
false );
}
@@ -837,7 +866,7 @@ int main( int argc, const char ** argv )
XMLNode* childNode0 = parent->InsertEndChild( childText0 );
XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true );
XMLTest( "Test InsertAfterChild on empty node. ", true, ( childNode1 == parent->LastChild() ) );
}
{
@@ -892,10 +921,11 @@ int main( int argc, const char ** argv )
XMLDocument doc( false );
doc.Parse( passages );
XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ),
"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;." );
XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(),
"Crazy &ttk;" );
XMLTest( "No entity parsing.",
"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.",
doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ) );
XMLTest( "No entity parsing.", "Crazy &ttk;",
doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value() );
doc.Print();
}
@@ -904,9 +934,9 @@ int main( int argc, const char ** argv )
XMLDocument doc;
doc.Parse( test );
XMLTest( "dot in names", doc.Error(), false );
XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
XMLTest( "dot in names", false, doc.Error() );
XMLTest( "dot in names", "a.elem", doc.FirstChildElement()->Name() );
XMLTest( "dot in names", "2.0", doc.FirstChildElement()->Attribute( "xmi.version" ) );
}
{
@@ -917,7 +947,7 @@ int main( int argc, const char ** argv )
XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
XMLTest( "Entity with one digit.",
text->Value(), "1.1 Start easy ignore fin thickness\n",
"1.1 Start easy ignore fin thickness\n", text->Value(),
false );
}
@@ -995,7 +1025,7 @@ int main( int argc, const char ** argv )
XMLDocument doc;
doc.Parse( "<test>&#x0e;</test>" );
const char result[] = { 0x0e, 0 };
XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result );
XMLTest( "Low entities.", result, doc.FirstChildElement()->GetText() );
doc.Print();
}
@@ -1003,18 +1033,18 @@ int main( int argc, const char ** argv )
// Attribute values with trailing quotes not handled correctly
XMLDocument doc;
doc.Parse( "<foo attribute=bar\" />" );
XMLTest( "Throw error with bad end quotes.", doc.Error(), true );
XMLTest( "Throw error with bad end quotes.", true, doc.Error() );
}
{
// [ 1663758 ] Failure to report error on bad XML
XMLDocument xml;
xml.Parse("<x>");
XMLTest("Missing end tag at end of input", xml.Error(), true);
XMLTest("Missing end tag at end of input", true, xml.Error());
xml.Parse("<x> ");
XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
XMLTest("Missing end tag with trailing whitespace", true, xml.Error());
xml.Parse("<x></y>");
XMLTest("Mismatched tags", xml.ErrorID(), XML_ERROR_MISMATCHED_ELEMENT);
XMLTest("Mismatched tags", XML_ERROR_MISMATCHED_ELEMENT, xml.ErrorID() );
}
@@ -1104,6 +1134,86 @@ int main( int argc, const char ** argv )
}
{
// Deep Cloning of root element.
XMLDocument doc2;
XMLPrinter printer1;
{
// Make sure doc1 is deleted before we test doc2
const char* xml =
"<root>"
" <child1 foo='bar'/>"
" <!-- comment thing -->"
" <child2 val='1'>Text</child2>"
"</root>";
XMLDocument doc;
doc.Parse(xml);
doc.Print(&printer1);
XMLNode* root = doc.RootElement()->DeepClone(&doc2);
doc2.InsertFirstChild(root);
}
XMLPrinter printer2;
doc2.Print(&printer2);
XMLTest("Deep clone of element.", printer1.CStr(), printer2.CStr(), true);
}
{
// Deep Cloning of sub element.
XMLDocument doc2;
XMLPrinter printer1;
{
// Make sure doc1 is deleted before we test doc2
const char* xml =
"<?xml version ='1.0'?>"
"<root>"
" <child1 foo='bar'/>"
" <!-- comment thing -->"
" <child2 val='1'>Text</child2>"
"</root>";
XMLDocument doc;
doc.Parse(xml);
const XMLElement* subElement = doc.FirstChildElement("root")->FirstChildElement("child2");
subElement->Accept(&printer1);
XMLNode* clonedSubElement = subElement->DeepClone(&doc2);
doc2.InsertFirstChild(clonedSubElement);
}
XMLPrinter printer2;
doc2.Print(&printer2);
XMLTest("Deep clone of sub-element.", printer1.CStr(), printer2.CStr(), true);
}
{
// Deep cloning of document.
XMLDocument doc2;
XMLPrinter printer1;
{
// Make sure doc1 is deleted before we test doc2
const char* xml =
"<?xml version ='1.0'?>"
"<!-- Top level comment. -->"
"<root>"
" <child1 foo='bar'/>"
" <!-- comment thing -->"
" <child2 val='1'>Text</child2>"
"</root>";
XMLDocument doc;
doc.Parse(xml);
doc.Print(&printer1);
doc.DeepCopy(&doc2);
}
XMLPrinter printer2;
doc2.Print(&printer2);
XMLTest("DeepCopy of document.", printer1.CStr(), printer2.CStr(), true);
}
{
// This shouldn't crash.
XMLDocument doc;
if(XML_SUCCESS != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))
@@ -1179,7 +1289,7 @@ int main( int argc, const char ** argv )
doc.Parse( xml );
XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
XMLTest( "Handle, success, mutable", ele->Value(), "sub" );
XMLTest( "Handle, success, mutable", "sub", ele->Value() );
XMLHandle docH( doc );
ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
@@ -1208,8 +1318,8 @@ int main( int argc, const char ** argv )
doc.Print( &printer );
static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
XMLTest( "BOM and default declaration", printer.CStr(), result, false );
XMLTest( "CStrSize", printer.CStrSize(), 42, false );
XMLTest( "BOM and default declaration", result, printer.CStr(), false );
XMLTest( "CStrSize", 42, printer.CStrSize(), false );
}
{
const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
@@ -1239,50 +1349,50 @@ int main( int argc, const char ** argv )
pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue );
XMLTest( "QueryIntText", intValue, 1, false );
XMLTest( "QueryUnsignedText", unsignedValue, (unsigned)1, false );
XMLTest( "QueryFloatText", floatValue, 1.2f, false );
XMLTest( "QueryDoubleText", doubleValue, 1.2, false );
XMLTest( "QueryBoolText", boolValue, true, false );
XMLTest( "QueryIntText", 1, intValue, false );
XMLTest( "QueryUnsignedText", (unsigned)1, unsignedValue, false );
XMLTest( "QueryFloatText", 1.2f, floatValue, false );
XMLTest( "QueryDoubleText", 1.2, doubleValue, false );
XMLTest( "QueryBoolText", true, boolValue, false );
}
{
const char* xml = "<element><_sub/><:sub/><sub:sub/><sub-sub/></element>";
XMLDocument doc;
doc.Parse( xml );
XMLTest( "Non-alpha element lead letter parses.", doc.Error(), false );
XMLTest( "Non-alpha element lead letter parses.", false, doc.Error() );
}
{
const char* xml = "<element _attr1=\"foo\" :attr2=\"bar\"></element>";
XMLDocument doc;
doc.Parse( xml );
XMLTest("Non-alpha attribute lead character parses.", doc.Error(), false);
XMLTest("Non-alpha attribute lead character parses.", false, doc.Error());
}
{
const char* xml = "<3lement></3lement>";
XMLDocument doc;
doc.Parse( xml );
XMLTest("Element names with lead digit fail to parse.", doc.Error(), true);
XMLTest("Element names with lead digit fail to parse.", true, doc.Error());
}
{
const char* xml = "<element/>WOA THIS ISN'T GOING TO PARSE";
XMLDocument doc;
doc.Parse( xml, 10 );
XMLTest( "Set length of incoming data", doc.Error(), false );
XMLTest( "Set length of incoming data", false, doc.Error() );
}
{
XMLDocument doc;
XMLTest( "Document is initially empty", doc.NoChildren(), true );
XMLTest( "Document is initially empty", true, doc.NoChildren() );
doc.Clear();
XMLTest( "Empty is empty after Clear()", doc.NoChildren(), true );
XMLTest( "Empty is empty after Clear()", true, doc.NoChildren() );
doc.LoadFile( "resources/dream.xml" );
XMLTest( "Document has something to Clear()", doc.NoChildren(), false );
XMLTest( "Document has something to Clear()", false, doc.NoChildren() );
doc.Clear();
XMLTest( "Document Clear()'s", doc.NoChildren(), true );
XMLTest( "Document Clear()'s", true, doc.NoChildren() );
}
// ----------- Whitespace ------------
@@ -1570,22 +1680,31 @@ int main( int argc, const char ** argv )
}
{
// Check that declarations are parsed only as the FirstChild
// Check that declarations are allowed only at beginning of document
const char* xml0 = "<?xml version=\"1.0\" ?>"
" <!-- xml version=\"1.1\" -->"
"<first />";
const char* xml1 = "<?xml version=\"1.0\" ?>"
" <?xml version=\"1.1\" ?>"
"<?xml-stylesheet type=\"text/xsl\" href=\"Anything.xsl\"?>"
"<first />";
const char* xml2 = "<first />"
"<?xml version=\"1.0\" ?>";
const char* xml3 = "<first></first>"
"<?xml version=\"1.0\" ?>";
const char* xml4 = "<first><?xml version=\"1.0\" ?></first>";
XMLDocument doc;
doc.Parse(xml0);
XMLTest("Test that the code changes do not affect normal parsing", doc.Error(), false);
XMLTest("Test that the code changes do not affect normal parsing", false, doc.Error() );
doc.Parse(xml1);
XMLTest("Test that the second declaration throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION);
XMLTest("Test that the second declaration is allowed", false, doc.Error() );
doc.Parse(xml2);
XMLTest("Test that declaration after a child throws an error", doc.ErrorID(), XML_ERROR_PARSING_DECLARATION);
XMLTest("Test that declaration after a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
doc.Parse(xml3);
XMLTest("Test that declaration after a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
doc.Parse(xml4);
XMLTest("Test that declaration inside a child is not allowed", XML_ERROR_PARSING_DECLARATION, doc.ErrorID() );
}
{
@@ -1604,11 +1723,221 @@ int main( int argc, const char ** argv )
{
XMLDocument doc;
for( int i = 0; i < XML_ERROR_COUNT; i++ ) {
doc.SetError( (XMLError)i, 0, 0 );
doc.SetError( (XMLError)i, 0, 0, 0 );
doc.ErrorName();
}
}
{
// Evil memory leaks.
// If an XMLElement (etc) is allocated via NewElement() (etc.)
// and NOT added to the XMLDocument, what happens?
//
// Previously (buggy):
// The memory would be free'd when the XMLDocument is
// destructed. But the destructor wasn't called, so that
// memory allocated by the XMLElement would not be free'd.
// In practice this meant strings allocated by the XMLElement
// would leak. An edge case, but annoying.
// Now:
// The destructor is called. But the list of unlinked nodes
// has to be tracked. This has a minor performance impact
// that can become significant if you have a lot. (But why
// would you do that?)
// The only way to see this bug is in a leak tracker. This
// is compiled in by default on Windows Debug.
{
XMLDocument doc;
doc.NewElement("LEAK 1");
}
{
XMLDocument doc;
XMLElement* ele = doc.NewElement("LEAK 2");
doc.DeleteNode(ele);
}
}
{
// Crashing reported via email.
const char* xml =
"<playlist id='playlist1'>"
"<property name='track_name'>voice</property>"
"<property name='audio_track'>1</property>"
"<entry out = '604' producer = '4_playlist1' in = '0' />"
"<blank length = '1' />"
"<entry out = '1625' producer = '3_playlist' in = '0' />"
"<blank length = '2' />"
"<entry out = '946' producer = '2_playlist1' in = '0' />"
"<blank length = '1' />"
"<entry out = '128' producer = '1_playlist1' in = '0' />"
"</playlist>";
// It's not a good idea to delete elements as you walk the
// list. I'm not sure this technically should work; but it's
// an interesting test case.
XMLDocument doc;
XMLError err = doc.Parse(xml);
XMLTest("Crash bug parsing", XML_SUCCESS, err );
XMLElement* playlist = doc.FirstChildElement("playlist");
XMLTest("Crash bug parsing", true, playlist != 0);
tinyxml2::XMLElement* entry = playlist->FirstChildElement("entry");
XMLTest("Crash bug parsing", true, entry != 0);
while (entry) {
tinyxml2::XMLElement* todelete = entry;
entry = entry->NextSiblingElement("entry");
playlist->DeleteChild(todelete);
};
tinyxml2::XMLElement* blank = playlist->FirstChildElement("blank");
while (blank) {
tinyxml2::XMLElement* todelete = blank;
blank = blank->NextSiblingElement("blank");
playlist->DeleteChild(todelete);
};
tinyxml2::XMLPrinter printer;
playlist->Accept(&printer);
printf("%s\n", printer.CStr());
// No test; it only need to not crash.
// Still, wrap it up with a sanity check
int nProperty = 0;
for (const XMLElement* p = playlist->FirstChildElement("property"); p; p = p->NextSiblingElement("property")) {
nProperty++;
}
XMLTest("Crash bug parsing", 2, nProperty);
}
// ----------- Line Number Tracking --------------
{
struct TestUtil: XMLVisitor
{
void TestParseError(const char *testString, const char *docStr, XMLError expected_error, int expectedLine)
{
XMLDocument doc;
XMLError err = doc.Parse(docStr);
XMLTest(testString, true, doc.Error());
XMLTest(testString, expected_error, err);
XMLTest(testString, expectedLine, doc.GetErrorLineNum());
};
void TestStringLines(const char *testString, const char *docStr, const char *expectedLines)
{
XMLDocument doc;
doc.Parse(docStr);
XMLTest(testString, false, doc.Error());
TestDocLines(testString, doc, expectedLines);
}
void TestFileLines(const char *testString, const char *file_name, const char *expectedLines)
{
XMLDocument doc;
doc.LoadFile(file_name);
XMLTest(testString, false, doc.Error());
TestDocLines(testString, doc, expectedLines);
}
private:
DynArray<char, 10> str;
void Push(char type, int lineNum)
{
str.Push(type);
str.Push(char('0' + (lineNum / 10)));
str.Push(char('0' + (lineNum % 10)));
}
bool VisitEnter(const XMLDocument& doc)
{
Push('D', doc.GetLineNum());
return true;
}
bool VisitEnter(const XMLElement& element, const XMLAttribute* firstAttribute)
{
Push('E', element.GetLineNum());
for (const XMLAttribute *attr = firstAttribute; attr != 0; attr = attr->Next())
Push('A', attr->GetLineNum());
return true;
}
bool Visit(const XMLDeclaration& declaration)
{
Push('L', declaration.GetLineNum());
return true;
}
bool Visit(const XMLText& text)
{
Push('T', text.GetLineNum());
return true;
}
bool Visit(const XMLComment& comment)
{
Push('C', comment.GetLineNum());
return true;
}
bool Visit(const XMLUnknown& unknown)
{
Push('U', unknown.GetLineNum());
return true;
}
void TestDocLines(const char *testString, XMLDocument &doc, const char *expectedLines)
{
str.Clear();
doc.Accept(this);
str.Push(0);
XMLTest(testString, expectedLines, str.Mem());
}
} tester;
tester.TestParseError("ErrorLine-Parsing", "\n<root>\n foo \n<unclosed/>", XML_ERROR_PARSING, 2);
tester.TestParseError("ErrorLine-Declaration", "<root>\n<?xml version=\"1.0\"?>", XML_ERROR_PARSING_DECLARATION, 2);
tester.TestParseError("ErrorLine-Mismatch", "\n<root>\n</mismatch>", XML_ERROR_MISMATCHED_ELEMENT, 2);
tester.TestParseError("ErrorLine-CData", "\n<root><![CDATA[ \n foo bar \n", XML_ERROR_PARSING_CDATA, 2);
tester.TestParseError("ErrorLine-Text", "\n<root>\n foo bar \n", XML_ERROR_PARSING_TEXT, 3);
tester.TestParseError("ErrorLine-Comment", "\n<root>\n<!-- >\n", XML_ERROR_PARSING_COMMENT, 3);
tester.TestParseError("ErrorLine-Declaration", "\n<root>\n<? >\n", XML_ERROR_PARSING_DECLARATION, 3);
tester.TestParseError("ErrorLine-Unknown", "\n<root>\n<! \n", XML_ERROR_PARSING_UNKNOWN, 3);
tester.TestParseError("ErrorLine-Element", "\n<root>\n<unclosed \n", XML_ERROR_PARSING_ELEMENT, 3);
tester.TestParseError("ErrorLine-Attribute", "\n<root>\n<unclosed \n att\n", XML_ERROR_PARSING_ATTRIBUTE, 4);
tester.TestParseError("ErrorLine-ElementClose", "\n<root>\n<unclosed \n/unexpected", XML_ERROR_PARSING_ELEMENT, 3);
tester.TestStringLines(
"LineNumbers-String",
"<?xml version=\"1.0\"?>\n" // 1 Doc, DecL
"<root a='b' \n" // 2 Element Attribute
"c='d'> d <blah/> \n" // 3 Attribute Text Element
"newline in text \n" // 4 Text
"and second <zxcv/><![CDATA[\n" // 5 Element Text
" cdata test ]]><!-- comment -->\n" // 6 Comment
"<! unknown></root>", // 7 Unknown
"D01L01E02A02A03T03E03T04E05T05C06U07");
tester.TestStringLines(
"LineNumbers-CRLF",
"\r\n" // 1 Doc (arguably should be line 2)
"<?xml version=\"1.0\"?>\n" // 2 DecL
"<root>\r\n" // 3 Element
"\n" // 4
"text contining new line \n" // 5 Text
" and also containing crlf \r\n" // 6
"<sub><![CDATA[\n" // 7 Element Text
"cdata containing new line \n" // 8
" and also containing cflr\r\n" // 9
"]]></sub><sub2/></root>", // 10 Element
"D01L02E03T05E07T07E10");
tester.TestFileLines(
"LineNumbers-File",
"resources/utf8test.xml",
"D01L01E02E03A03A03T03E04A04A04T04E05A05A05T05E06A06A06T06E07A07A07T07E08A08A08T08E09T09E10T10");
}
// ----------- Performance tracking --------------
{
#if defined( _MSC_VER )
@@ -1618,7 +1947,7 @@ int main( int argc, const char ** argv )
FILE* perfFP = fopen("resources/dream.xml", "r");
fseek(perfFP, 0, SEEK_END);
long size = ftell(fp);
long size = ftell(perfFP);
fseek(perfFP, 0, SEEK_SET);
char* mem = new char[size + 1];
@@ -1664,6 +1993,11 @@ int main( int argc, const char ** argv )
_CrtMemState diffMemState;
_CrtMemDifference( &diffMemState, &startMemState, &endMemState );
_CrtMemDumpStatistics( &diffMemState );
{
int leaksBeforeExit = _CrtDumpMemoryLeaks();
XMLTest( "No leaks before exit?", FALSE, leaksBeforeExit );
}
#endif
printf ("\nPass %d, Fail %d\n", gPass, gFail);