Compare commits

..

523 commits
v1.7 ... master

Author SHA1 Message Date
Arseny Kapoulkine
1dc3266fff docs: Add missing documentation for xml_node::attribute with hint
The feature was added in 2015 but somehow was never documented.
2022-11-08 16:49:34 -08:00
Arseny Kapoulkine
cb217f5a85
Merge pull request #530 from zeux/snprintf
Fix Xcode 14 sprintf deprecation warning
2022-11-06 15:09:53 -08:00
Arseny Kapoulkine
e11e0c965f Fix comment typo. 2022-11-06 13:47:53 -08:00
Arseny Kapoulkine
b6b747244e Adjust the workaround for -pedantic mode and fix tests 2022-11-06 10:21:35 -08:00
Arseny Kapoulkine
8be081fbbe Fix Xcode 14 sprintf deprecation warning
We use snprintf when stdc is set to C++11, however in C++98 mode we can't use variadic macros,
and Xcode 14 complains about the use of sprintf.

It should be safe however to use variadic macros on any remotely recent version of clang on Apple,
unless -pedantic is defined which warns against the use of variadic macros in C++98 mode...

This change fixes the problem for the builds that don't specify -pedantic, which is a problem for
another day.
2022-11-06 10:16:21 -08:00
Arseny Kapoulkine
a0e0643363
Merge pull request #526 from zeux/newver
Prepare for 1.13 release
2022-10-28 16:53:25 -07:00
Arseny Kapoulkine
3bd1f452b5 Fix version check in test 2022-10-20 20:23:26 -07:00
Arseny Kapoulkine
c5b288d91a Update HTML documentation 2022-10-20 20:20:45 -07:00
Arseny Kapoulkine
0ef3da1e6e Update release notes and manual for 1.13
This includes a previously unnoticed link fix for xml_text::set
2022-10-20 20:18:08 -07:00
Arseny Kapoulkine
76dcd89427 Update version number in preparation for 1.13 2022-10-20 20:08:52 -07:00
Arseny Kapoulkine
43ef7e25d9
Merge pull request #525 from bruxisma/master
Fix exported symbols under clang-cl (Closes #503)
2022-10-20 19:49:48 -07:00
Izzy Muerte
ab8af53059 Fix exported symbols under clang-cl (Closes #503)
This also turns the define for PUGIXML_API into an `$<IF:>`, instead of an
`$<IF:>` with an empty true condition. If this is inadequate, I will
undo it, and place them on separate lines as they were before, but will
most likely use an inverse `$<NOT:>` instead of an `$<IF:>`.
2022-10-20 13:35:49 -07:00
Arseny Kapoulkine
86c9105154
Merge pull request #523 from zeux/ferrh
Fix error handling in xml_document::save_file
2022-10-09 09:08:50 -07:00
Arseny Kapoulkine
444963e269 Fix error handling in xml_document::save_file
There were two conditions under which xml_document::save_file could
previously return true even though the saving failed:

- The last write to the file was buffered in stdio buffer, and it's that
  last write that would fail due to lack of disk space
- The data has been written correctly but fclose failed to update file
  metadata, which can result in truncated size / missing inode updates.

This change fixes both by adjusting save_file to fflush before the check,
and also checking fclose results. Note that while fflush here is
technically redundant, because it's implied by fclose, we must check
ferror explicitly anyway, and so it feels a little cleaner to do most of
the error handling in save_file_impl, so that the changes of fclose()
failing are very slim.

Of course, neither change guarantees that the contents of the file are
going to be safe on disk following a power failure.
2022-10-07 22:13:04 -07:00
Arseny Kapoulkine
0cb4f02579 Final tweaks after #522
This cleans up xml_attribute::set_value to be uniform wrt
xml_node::set_value and xml_text::set_value - for now we duplicate the
body since the logic is trivial and this keeps debug performance
excellent.
2022-10-07 21:46:27 -07:00
Arseny Kapoulkine
c342266fae
Merge pull request #522 from Ferenc-/followup-on-pr-490
Followup on pr 490
2022-10-07 21:42:41 -07:00
Ferenc Géczi
39e169285c Add test for xml_attribute::set_value with size argument 2022-09-29 00:00:00 +00:00
Ferenc Géczi
1905284494 Add test for xml_node::set_value with size argument 2022-09-29 00:00:00 +00:00
Ferenc Géczi
d359402311 Add xml_text::set test with size set to substring 2022-09-29 00:00:00 +00:00
Ferenc Géczi
09e7cc9b1c Add test for xml_text::set with size argument 2022-09-29 00:00:00 +00:00
Ferenc Géczi
f327371219 Add overloads with size_t type argument
* xml_node::set_value(const char_t* rhs, size_t sz)
* xml_text::set(const char_t* rhs, size_t sz)

Signed-off-by: Ferenc Géczi <ferenc.gm@gmail.com>
2022-09-29 18:26:05 +00:00
Arseny Kapoulkine
bcf483c3b7
Merge pull request #492 from KDAB/fix-default-visibility
Correctly set default visibility on non-windows compilers
2022-09-27 12:53:06 -07:00
Milian Wolff
173a263490 Correctly set default visibility on non-windows compilers
This fixes compilation of pugixml with -fvisibility=hidden. Without
this patch, one would get lots of unresolved symbols when consuming
pugixml as a shared library.
2022-09-25 11:37:48 +02:00
Arseny Kapoulkine
521b2cd854 Add issue templates to try to route questions to Discussions 2022-09-02 21:42:25 -07:00
Arseny Kapoulkine
27bc68ab45
Merge pull request #506 from brandl-muc/nullptr_for_msvc
Enable usage of nullptr for MSVC 16 and newer (MSVS 2010)
2022-08-04 08:46:13 -07:00
Matthäus Brandl
f7de324855 Enable usage of nullptr for MSVC 16 and newer (MSVS 2010) 2022-08-04 16:59:37 +02:00
Arseny Kapoulkine
3b5c1fb022 tests: Fix MSVC 2005 build
... I forgot we still support platforms without C99, 23 years later.
2022-07-21 21:17:17 -07:00
Arseny Kapoulkine
ab8453c572 tests: Use snprintf instead of sprintf
sprintf now results in a deprecation warning in Xcode 14 beta.
2022-07-21 20:51:26 -07:00
Arseny Kapoulkine
2639dfd053
Merge pull request #477 from zeux/compactopt
Optimize compact mode
2022-05-31 20:00:01 -05:00
Arseny Kapoulkine
0401559dde
Merge pull request #498 from zeux/fix-oom-safer
Fix memory leak during OOM in convert_buffer
2022-05-16 20:50:07 -07:00
Arseny Kapoulkine
832a4f4914 Use more idiomatic code in this codebase 2022-05-16 19:14:29 -07:00
Arseny Kapoulkine
33a75c734b Fix memory leak during OOM in convert_buffer
This is the same fix as #497, but we're using auto_deleter instead
because if allocation function throws, we can't rely on an explicit call
to deallocate.

Comes along with two tests that validate the behavior.
2022-05-16 19:12:52 -07:00
Arseny Kapoulkine
ec851bb18d
Merge pull request #497 from TodorHryn/master
Fix memory leak
2022-05-16 19:05:29 -07:00
TodorHryn
6fbf32140b Fix memory leak 2022-05-16 13:21:20 +03:00
Viktor Govako
effc46f0ed Added bool set_value(const char_t* rhs, size_t sz). 2022-04-13 12:25:01 +03:00
Arseny Kapoulkine
363ebdde91
Merge pull request #482 from zeux/fix-msvc-test
tests: Fix MSVC 2022 build
2022-02-15 21:12:03 -08:00
Arseny Kapoulkine
c60ca94cdd tests: Fix MSVC 2022 build
Instead of trying to detect if we can safely use random shuffle simply reimplement it ourselves.
The quality of the RNG is not essential for these tests.
2022-02-15 20:23:05 -08:00
Arseny Kapoulkine
dd50fa5b45 Fix PUGIXML_VERSION macro
Also make sure the line shows up in grep when using the current version
number.

Fixes #478.
2022-02-10 08:36:19 -08:00
Arseny Kapoulkine
2fa9158b4f Optimize compact mode: xml_text 2022-02-08 23:04:31 -08:00
Arseny Kapoulkine
fad2d5e4ef Optimize compact mode: xml_attribute/xml_node implementation 2022-02-08 23:00:17 -08:00
Arseny Kapoulkine
f388c465dd Optimize compact mode: reuse access in insert/remove 2022-02-08 22:44:31 -08:00
Arseny Kapoulkine
314baf6605 docs: Regenerate HTML documentation 2022-02-08 20:09:10 -08:00
Arseny Kapoulkine
eb918f2078 docs: Update manual with 1.12 changelog 2022-02-08 19:59:44 -08:00
Arseny Kapoulkine
25c4fb74a8 Update copyright year to 2022 2022-02-08 19:58:58 -08:00
Arseny Kapoulkine
c9e219c17b Update version to 1.12 2022-02-08 19:56:41 -08:00
Arseny Kapoulkine
9ba92a7fa7 Restore compatibility with WinCE
WinCE lacks most recent CRT additions to MSVC; we used to explicitly disable specific sections
of code, but it's more comprehensive to just specify that the CRT is from MSVC7 instead of MSVC8.

Fixes #401
2022-02-08 19:19:34 -08:00
Arseny Kapoulkine
6ce48ec379
Merge pull request #468 from appls/master
Add support for Visual Studio 2022 with Platform Toolset v143.
2022-02-08 12:43:53 -08:00
Arseny Kapoulkine
428606b3c1
Create SECURITY.md
Fixes #475
2022-02-06 09:13:33 -08:00
tobias
64de196ba9 Fix path. 2022-01-21 15:56:25 +01:00
tobias
bd90579718 Add missing build script and test script entries for appveyor. 2022-01-21 15:44:39 +01:00
tobias
16a4f382ac Add missing appveyor test config for Visual Studio 2022. 2022-01-21 15:30:45 +01:00
tobias
bc2448afbb Add support for Visual Studio 2022 with Platform Toolset v143. 2022-01-21 15:06:27 +01:00
Arseny Kapoulkine
9e382f9807
Merge pull request #436 from zeux/zeux-patch-1
Set CMP0091 CMake policy
2021-08-07 19:06:12 -07:00
Arseny Kapoulkine
f1fbd707f1
Set CMP0091 CMake policy
This allows the correct use of runtime library override.

Fixes #412
2021-08-07 09:57:21 -07:00
Arseny Kapoulkine
a5991972ba
Merge pull request #426 from bjornblissing/feature/cmake_pugiconfig
Add Cmake options for pugiconfig.hpp options

Fixes #387 
Closes #388
2021-08-07 09:54:18 -07:00
Arseny Kapoulkine
c624c7a8bd
Update CMakeLists.txt
Remove memory configuration options and rely on automatic detection of long long
2021-08-07 09:51:54 -07:00
Arseny Kapoulkine
8bd209fb8b docs: Update manual to be more explicit about save_file return
The function returns true on success and false on failure.
2021-07-09 17:27:01 -07:00
Arseny Kapoulkine
657619962f
Merge pull request #431 from justinkb/master
Fix include in test_document.cpp when building against libc++. The _GLIBCXX_HAVE_UNISTD_H relies on pugixml and its tests being built against libstdc++, with LLVM's libc++ this won't be defined
2021-06-30 14:28:44 -07:00
Paul Mulders
81274bb026 Fix include in test_document.cpp when building against libc++ 2021-06-30 23:07:54 +02:00
Arseny Kapoulkine
37eddaa0b2
Update .codecov.yml
Mark "project" check as information and disable "patch" check.
2021-06-30 13:11:45 -07:00
Björn Blissing
e7eae035ff Store definitions in variable to avoid duplication
Store compile definitions in variable to avoid duplicated generator
expressions.
2021-06-28 19:51:20 +02:00
Björn Blissing
52a7981b85 Make some compile definitions public
Moved needed defines to public section of target_compile_definitions.
2021-06-28 13:36:55 +02:00
Björn Blissing
92ac6ac1d9 Update github action to trigger defines via CMake
Use options via explicit CMake defines, instead of calling them from
the generic PUGI_BUILD_DEFINES variable.
2021-06-28 13:17:06 +02:00
Björn Blissing
50b103f127 Fix generator expressions 2021-06-28 13:17:06 +02:00
Björn Blissing
1cd65c7eb8 Move advanced memory settings into target defs.
Moved the advanced memory options into target_compile_definitions using
generator expressions.
2021-06-28 12:50:27 +02:00
Björn Blissing
f1946432ee Check for existence of long long 2021-06-28 12:50:27 +02:00
Björn Blissing
e2ba4f4014 Add options to build targets
Add custom options to the build targets via generator expressions.
2021-06-28 12:50:27 +02:00
Björn Blissing
5f49f2c657 Mark advanced options and removed redundant ones
Options marked as advanced are hidden by default in the CMake GUI.

The `PUGIXML_HEADER_ONLY` are redundant when during CMake builds, hence
removed.

The `PUGIXML_HAS_LONG_LONG` should be handled automatically and needs to
be rewritten, hence these options has been removed.
2021-06-28 12:50:27 +02:00
Björn Blissing
986b7ffd01 Add Cmake options for pugiconfig.hpp
Add Cmake options variables for each of the defines in pugiconfig.hpp.
2021-06-28 12:50:27 +02:00
Arseny Kapoulkine
06a516c73c
Merge pull request #428 from zeux/gha
Switch to GitHub Actions build from Travis CI
2021-06-27 20:08:57 -07:00
Arseny Kapoulkine
a6a63a1b50 gcov crashes on LLVM-produced coverage on Linux 2021-06-27 19:27:40 -07:00
Arseny Kapoulkine
5cff00e5ea Fix coverage build to include CXX define
Also it seems like we don't need to restrict coverage build to
Linux/clang?
2021-06-27 19:20:27 -07:00
Arseny Kapoulkine
0de580155d Don't run GHA workflow on push to branches
Also convert line endings to Unix.
2021-06-27 19:12:59 -07:00
Arseny Kapoulkine
e7b545b288 Remove custom job name for unix 2021-06-27 19:09:08 -07:00
Arseny Kapoulkine
3097a2c711 Switch to export and GH vars 2021-06-27 19:04:15 -07:00
Arseny Kapoulkine
8bd9a19a7e Change badge to GHA badge.
So long, Travis.
2021-06-27 19:01:06 -07:00
Arseny Kapoulkine
0b793a3126 Add GitHub Actions based build 2021-06-27 19:00:18 -07:00
Arseny Kapoulkine
7da44ddc5b
Merge pull request #399 from bjornblissing/feature/cmake_prefix
Add PUGIXML as prefix to CMake options
2021-06-22 14:32:00 -07:00
Björn Blissing
7b1b7ee16d Reverted to use of global BUILD_SHARED_LIBS option
This commit reverts back to exposing the global variable
BUILD_SHARED_LIBS.

Since building static libraries are the default for CMake
(i.e. BUILD_SHARED_LIBS=OFF) the option to build both static and shared
libraries were moved into a conditional option. So the option
PUGIXML_BUILD_SHARED_AND_STATIC is now only visible when the global
BUILD_SHARED_LIBS variable is set to ON.

The change also prevents the case were the user first enables
BUILD_SHARED_LIBS and then enables PUGIXML_BUILD_SHARED_AND_STATIC to
then again disable BUILD_SHARED_LIBS.
2021-06-19 12:51:27 +02:00
Björn Blissing
fc7928a4b7 Use target_compile_definitions for custom defines
Replace `add_definitions` with `target_compile_definitions` for
specified targets. Multiple options are separated using the
`separate_arguments` function, which converts any string using
space-separated arguments into a semicolon-separated list.
2021-06-19 11:22:31 +02:00
Björn Blissing
0f1e75a902 Re-introduced the custom build defines
The ability to use custom build defines were removed in commit:
1c5a0bb325

This commit will reintroduce this feature, but using a prefixed variable
name.
2021-06-15 09:00:31 +02:00
Björn Blissing
91fde92fc2 Add PUGIXML as prefix to CMake options
Added PUGIXML as prefix to all CMake options to avoid naming collisions
with downstream projects.

Removed the cached variable BUILD_DEFINES, since it was unused.
2021-06-15 08:42:30 +02:00
Arseny Kapoulkine
5c4225b5c9 tests: Fix wchar_t build 2021-05-11 23:22:13 -07:00
Arseny Kapoulkine
8cece4b9fe Fix a bug in move construction when move source is empty
Previously when copying the allocator state we would copy an incorrect
root pointer into the document's current state; while this had a minimal
impact on the allocation state due to the fact that any new allocation
would need to create a new page, this used a potentially stale field of
the moved document when setting up new pages, which could create issues
in future uses of the pages.

This change fixes the core problem and also removes the use of the
_root->allocator from allocate_page since it's not clear why we need it
there in the first place.
2021-05-11 22:53:54 -07:00
Arseny Kapoulkine
56c9afa7c8 XPath: Improve recursion limit for deep chains of //
Since foo//bar//baz adds two nodes for each //, we need to increment the
depth by 2 on each iteration to limit the AST correctly.

Fixes the stack overflow found by cluster-fuzz (I suspect the issue
there is a bit deeper, but this part is definitely a bug and as such I'd
rather wait for the next test case for now).
2021-05-11 22:27:53 -07:00
Arseny Kapoulkine
791971ee59
Merge pull request #422 from neheb/patch-1
fix cygwin compilation
2021-05-07 00:35:47 -07:00
Rosen Penev
e672b1c9f0
fix cygwin compilation 2021-05-06 23:25:29 -07:00
Arseny Kapoulkine
5df537f348
Merge pull request #419 from neheb/ranges
add empty method
2021-04-27 23:37:06 -07:00
Rosen Penev
c167259e60 add empty method
Simple and allows to avoid using std::distance.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-04-27 13:55:02 -07:00
Arseny Kapoulkine
5d58e94b6d
Merge pull request #418 from neheb/ranges
remove const from xml_node_iterator ++/--

Fixes #417.
2021-04-26 14:32:51 -07:00
Rosen Penev
ef257796db remove const from operator++/--
This prevents usage with C++20 ranges since it does not satisfy
std::weakly_incrementable.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-04-26 14:06:19 -07:00
Arseny Kapoulkine
08b3433180
Merge pull request #394 from zeux/cmake-yay
Don't define pugixml import target if it already exists
2020-12-22 08:41:08 -08:00
Arseny Kapoulkine
06868c8f57 Don't define pugixml import target if it already exists
This fixes duplicate target definition errors when find_package(pugixml)
is called twice in a build.

Fixes #393.
2020-12-22 08:15:11 -08:00
Arseny Kapoulkine
0e3f1699ff
Merge pull request #391 from zeux/cmake-omg
Fix compatibility issue with CMake 3.10
2020-12-18 09:52:06 -08:00
Arseny Kapoulkine
e2bc4f4af2 Fix compatibility issue with CMake 3.10
target_link_libraries/INTERFACE doesn't seem to work on CMake 3.10, but
directly setting the property does work.

Fixes #390.
2020-12-18 09:07:44 -08:00
Arseny Kapoulkine
907955280f
Merge pull request #389 from mathstuf/fix-alias-compat-target
cmake: avoid ALIAS target
2020-12-14 19:47:56 -08:00
Ben Boeckel
4feab60bb7 cmake: avoid ALIAS target
This is not allowed on IMPORTED targets.
2020-12-10 12:02:01 -05:00
Arseny Kapoulkine
5a0fd5d85f docs: Rebuild HTML documentation 2020-12-04 16:31:20 -08:00
Arseny Kapoulkine
68a92aa972
Merge pull request #384 from mathstuf/update-1.11-release-notes
Update 1.11 release notes
2020-12-04 15:59:40 -08:00
Ben Boeckel
d1d415e666 docs: add a note about the new imported target name for CMake 2020-12-02 17:17:21 -05:00
Ben Boeckel
5063e87499 cmake: provide a compatibility target for users
For users using older pugixml releases, add an ALIAS target which works
with the new versions too.
2020-12-02 17:16:47 -05:00
Arseny Kapoulkine
7a9da11d8b scripts: Convert archive.py to Python 3
The changes are mostly mechanically converting str to bytes.
2020-11-26 01:08:07 -08:00
Arseny Kapoulkine
a3ae05cc9f scripts: Remove deprecated iconUrl from NuGet package
The logo.svg link is dead anyway.
2020-11-26 01:01:57 -08:00
Arseny Kapoulkine
fe4bc946b2 Update copyright year to 2020 everywhere 2020-11-26 01:00:27 -08:00
Arseny Kapoulkine
632c042a35
Merge pull request #383 from zeux/next-release
Update version to 1.11 and update documentation
2020-11-25 14:37:35 -08:00
Arseny Kapoulkine
70bd6a6b0a Update version to 1.11 and update documentation 2020-11-25 10:18:42 -08:00
Arseny Kapoulkine
8afc1239a3 tests: Fix test fallout for MSVC6
One more XPath test falls prey to MSVC6 NaN comparison codegen issues.
2020-11-25 09:48:19 -08:00
Arseny Kapoulkine
5f97d5d66f Fix -Wshadow in remove_children()
child variable was shadowing xml_node::child
2020-11-25 09:28:26 -08:00
Arseny Kapoulkine
28aebf2b22
Merge pull request #382 from zeux/TheNicker-master
Fix MSVC deprecation warnings when using clang-cl
2020-11-25 09:19:24 -08:00
Arseny Kapoulkine
df42668e18 Cleanup code and feature detection
We now use open_file similarly to open_file_wide, and activate the
workaround for MSVC 2005+ since that's when the _s versions were added
in the first place.
2020-11-25 08:38:22 -08:00
Arseny Kapoulkine
30761e48df
Merge pull request #376 from jjmccollum/mingw-dll-fix
Added fix to pugixml_dll.rc so shared lib can be built with MinGW
2020-10-26 15:48:58 -07:00
James McCollum
24e454066d Added fix to pugixml_dll.rc so shared lib can be built with MinGW 2020-10-26 08:17:46 -04:00
Arseny Kapoulkine
c4bae8d818
Merge pull request #370 from zeux/xpath-rec
XPath: Fix stack overflow in functions with long argument lists
2020-09-11 13:06:44 -07:00
Arseny Kapoulkine
8e5b8e0f46 XPath: Fix stack overflow in functions with long argument lists
Function call arguments are stored in a list which is processed
recursively during optimize(). We now limit the depth of this construct
as well to make sure optimize() doesn't run out of stack space.
2020-09-11 09:50:41 -07:00
Arseny Kapoulkine
a3fad540a7
Merge pull request #369 from zeux/xpath-rec
XPath: Restrict AST depth to prevent stack overflow
2020-09-10 09:53:25 -07:00
Arseny Kapoulkine
20aef1cd4b Fix stack overflow in tests on MSVC x64
The default stack on MSVC/x64/debug is sufficient for 1692 nested
invocations only, whereas on clang/linux it's ~8K...

For now set the limit to be conservative.
2020-09-10 09:11:46 -07:00
Arseny Kapoulkine
c7090e6c33 Fix tests in wchar mode 2020-09-10 01:07:48 -07:00
Arseny Kapoulkine
1f84db837b XPath: Restrict AST depth to prevent stack overflow
XPath parser and execution engine isn't stackless; the depth of the
query controls the amount of C stack space required.

This change instruments places in the parser where the control flow can
recurse, requiring too much C stack space to produce an AST, or where a
stackless parse is used to produce arbitrarily deep AST which will
create issues for downstream processing.

As a result XPath parser should now be fuzz safe for malicious inputs.
2020-09-10 00:55:26 -07:00
Lior Lahav
c258fba6f1 Replaced fopen and _wfopen deprecated functions with the safer fopen_s and _wfopen_s 2020-07-21 22:37:16 +03:00
Arseny Kapoulkine
22401bafaf
Merge pull request #363 from c72578/2020-07-15_Fix_pkgconfig_lib_postfix
Fix debug postfix in pkgconfig file
2020-07-15 14:05:14 -07:00
Wolfgang Stöggl
8b074b171f Fix debug postfix in pkgconfig file
In case of USE_POSTFIX, the POSTFIX is dependent
on the CMAKE_BUILD_TYPE.
Use the correct POSTFIX also in the generated pugixml.pc file.

This results in the following contents of pugixml.pc:
- Release:
  Libs: -L${libdir} -lpugixml
- RelWithDebInfo
  Libs: -L${libdir} -lpugixml_r
- MinSizeRel:
  Libs: -L${libdir} -lpugixml_m
- Debug:
  Libs: -L${libdir} -lpugixml_d
2020-07-15 21:59:05 +02:00
Arseny Kapoulkine
d58115e581
Merge pull request #360 from julianxhokaxhiu/patch-1
[Cmake] Static build should not export APIs
2020-07-06 09:22:06 -07:00
Arseny Kapoulkine
45271c9c9c
Merge pull request #361 from zeux/ps-stderr
Fix PowerShell errors on stderr
2020-07-06 09:21:46 -07:00
Arseny Kapoulkine
f08768d9bf Fix PowerShell errors on stderr
PS invocation of code coverage upload gets triggered because of stderr
output from curl with progress report when uploading coverage.
2020-07-06 08:32:24 -07:00
Julian Xhokaxhiu
5fdc78b66b
[Cmake] Static build should not export APIs
Fixes #359
2020-07-06 10:22:21 +02:00
Arseny Kapoulkine
23ca940487 Work around a false positive in MSVC debug runtime checker
In some MSVC versions on x64 configurations, the hashing function
triggers this failure:

Run-Time Check Failure #1 - A cast to a smaller data type has caused a
loss of data.  If this was intentional, you should mask the source of
the cast with the appropriate bitmask.

This is similar to the integer sanitizer - this code is valid C++ but
MSVC decides to warn about this nonetheless. Masking the pointer's low
32 bits fixes the issue.

Fixes #357.
2020-06-13 08:41:22 -07:00
Arseny Kapoulkine
a196b9b7e9
Merge pull request #353 from jhasse/nullptr-in-header
Use nullptr in pugixml.hpp if available, see #91
2020-05-11 10:26:05 -07:00
Jan Niklas Hasse
c2d90c49f9 Use nullptr in pugixml.hpp if available, see #91 2020-05-10 17:28:30 +02:00
Arseny Kapoulkine
f49d7acdfb Clarify the document element behavior.
pugixml currently unconditionally accepts documents with multiple
top-level element nodes in absence of parse_fragment. This is an
unfortunate omission; while it can be corrected, it will result in
regressions for some users, and it's trivial to perform the validity
check after the parse is done.

Because of this, for now we're just going to amend documentation here to
both highlight this in the W3C Conformance section, but also to more
strongly push users into realizing that there's just a single document
element (normally).

We might decide to change the behavior here to prohibit such documents
by default in the future, but for now a documentation change seems like
a better tradeoff.

Fixes #337
2020-05-02 09:47:34 -07:00
Arseny Kapoulkine
285776354d
Merge pull request #349 from KyleFromKitware/cmake-improvements
Various CMake improvements
2020-05-02 09:36:58 -07:00
Kyle Edwards
d272f11073 Export targets from build directory
This will allow projects to use pugixml from its build directory
rather than having to install it.
2020-04-27 16:02:56 -04:00
Arseny Kapoulkine
ef9cafa9ce
Merge pull request #348 from rip-nsk/source_and_header-only_linkage_options
Add "Include pugixml.cpp" and "Header Only" linkage options
2020-04-27 11:15:15 -07:00
Kyle Edwards
184e6ed916 Use COMPONENT arguments in install() commands 2020-04-27 13:47:58 -04:00
Kyle Edwards
8c74d8b198 Fix multiple-rules-for-target error
The old logic for BUILD_SHARED_LIBS and BUILD_SHARED_AND_STATIC_LIBS
would produce two targets with the same name and different build
rules. The Makefile generator tolerated this, but the Ninja generator
raised an error. Fix the logic so that only one shared and one static
target gets built, and make the pugixml target an ALIAS of the one
dictated by BUILD_SHARED_LIBS.
2020-04-27 13:47:58 -04:00
rip.nsk
ab86960e48 Add "Include pugixml.cpp" and "Header Only" linkage options 2020-04-24 17:56:46 -07:00
Arseny Kapoulkine
5e64076af9 Adjust node_copy_tree to be more explicit about invariants
The loop traverses the source tree and simultaneously builds up a copy
of it at destination. Short of race conditions, this code is safe -
however, it's not obvious that dit stays inside the destination tree.

This change adds a few assertions to help enforce/document these
invariants. One particular subtlety is that dit can actually *become*
null after we exit out of the loop, but it's guaranteed to only do so
once sit goes back to sn.

This is only possible when doing a full document copy - for some reason
we weren't using this for that (in reset(xml_document)), but we are now.

Fixes #314.
2020-02-19 21:02:33 -08:00
Arseny Kapoulkine
76c3914484 XPath: Remove the use of fallthrough switch cases
We were previously relying on non-standard comment detection that is
supported by gcc/clang to avoid warnings about implicit fallthrough.

This can be solved using attributes but using them requires a lot of
compiler-specific detection logic because not all versions of gcc/clang
support them.

We don't *really* need to rely on fallthrough here - the type conversion
block can be located *after* the AST type switch instead, which means
that any AST type that has type ambiguity can fall back to that in the
future.

Fixes #331.
2020-02-19 07:50:59 -08:00
Arseny Kapoulkine
6fbe927575
Merge pull request #330 from LocutusOfBorg/patch-2
Update CMakeLists.txt to rename the static and shared libraries to pugixml
2020-02-07 23:08:22 -08:00
Gianfranco Costamagna
2c24e90c23
Update CMakeLists.txt to rename the static and shared libraries to pugixml
Don't call them pugixml-shared or pugixml-static, because this breaks pkgconfig calls and userspace tools.
2020-02-07 14:55:25 +01:00
Arseny Kapoulkine
546cafefa3 XPath: Add a clarification comment for ast_variable fallthrough 2020-02-01 07:48:45 -08:00
Arseny Kapoulkine
85a39b955d tests: Add a dedicated test for XPath variable conversion
This makes sure all conversions work as expected (note that no type can
be converted to node set so we don't check that).
2020-02-01 07:44:14 -08:00
Arseny Kapoulkine
41b6ff21c4
Merge pull request #316 from BotellaA/patch-1
Add POSITION_INDEPENDENT_CODE option
2019-12-20 08:13:28 -08:00
Arnaud Botella
aa2e0909ac
Add POSITION_INDEPENDENT_CODE option
Allow to use the static library in other dynamic librairies. This is a standard cmake option https://cmake.org/cmake/help/v3.11/prop_tgt/POSITION_INDEPENDENT_CODE.html#prop_tgt:POSITION_INDEPENDENT_CODE
2019-12-06 17:25:37 +01:00
Arseny Kapoulkine
53a30c6571 Cleanup first_element_by_path
Instead of performing a late null check that is redundant and only
needed to silence clang static analysis warning, we pick the context as
a root / self node. This way the code is a bit less redundant and the
static analyzer is happy.
2019-12-03 21:23:15 -08:00
Arseny Kapoulkine
2e8631d2eb
Merge pull request #313 from valeriyvan/nulldereference
Fixing possible null pointer dereference
2019-12-03 21:17:28 -08:00
Valeriy Van
cda8623468 Fixing possible null pointer dereference 2019-12-02 15:02:54 +01:00
Arseny Kapoulkine
51d177e938
Merge pull request #310 from amlucas/master
explicit casts for -Wconversions warnings in gcc
2019-11-27 17:50:21 +01:00
Lucas Amoudruz
78e98c446d explicit casts for -Wconversions warnings in gcc 2019-11-27 15:56:05 +01:00
Arseny Kapoulkine
fe5460c6dc
Merge pull request #305 from slurps-mad-rips/modern-cmake
Fix incorrect installation location for exported CMake targets
2019-10-17 22:07:54 -07:00
Isabella Muerte
99ad261611 🐛 Fix incorrect installation location for exported CMake targets 2019-10-17 21:44:48 -07:00
Arseny Kapoulkine
40be014e48
Merge pull request #303 from slurps-mad-rips/modern-cmake
Fix install locations for pkgconfig *and* cmake
2019-10-06 15:45:55 -07:00
Isabella Muerte
6949232bbd 🐛 Fix install locations for pkgconfig *and* cmake 2019-10-06 13:08:01 -07:00
Arseny Kapoulkine
fdd618f13a
Merge pull request #302 from slurps-mad-rips/modern-cmake
Modernize CMake
2019-10-06 12:44:43 -07:00
Isabella Muerte
3df5036344 🔥 Remove commented out CMake code 2019-10-06 12:33:03 -07:00
Isabella Muerte
ad93a373ab Adjust MSVC runtime settings as requested.
The block of code can be removed in the future if CMake 3.15 ever
becomes the minimum
2019-10-01 10:20:30 -07:00
Isabella Muerte
8a0aac18ea Update check command to output text on failure
Move pugixml-config.cmake.in to scripts/ to prevent polluting the root
2019-09-30 22:00:04 -07:00
Isabella Muerte
1c5a0bb325 Update CMake to modern approach
New Features:

pugixml-shared and pugixml-static are "always" available, but not always
built. This allows downstream projects to still use them, and to make
sure our configurations are correct regardless of if they are being
built. They are not always installed however.

pugixml-shared and pugixml-static have ALIAS libraries of
pugixml::shared and pugixml::static respectively. These names are also
respected in the `find_package(pugixml CONFIG)` generated files, so its
safe to use pugixml in a CMake project regardless of whether it is
installed locally, or if its a subproject via `add_subdirectory`.

pugixml will automatically select the correct library type based on
BUILD_SHARED_LIBS. A pugixml::pugixml ALIAS is also available.

CMAKE_MSVC_RUNTIME_LIBRARY from CMake 3.15 has been backported.

CMake will now rely on generator expressions (a powerful abstraction in
large projects with many subdirectories) for most work. This offloads
work from the single-threaded configure stage to the multithreaded
generation stage.

pugixml now uses CTest as the runner.

Some settings are automatically disabled if pugixml is used as a
subdirectory. These are still able to be manually set, but are hidden
from folks who choose to use CMake GUI.
2019-09-28 13:02:55 -07:00
Isabella Muerte
195dfe1d8d 🚧 Begin moving pugixml to modern(ish) CMake
⬆️ Bump CMake minimum to 3.4
🐛 pugixml no longer requires a C compiler to be found or set to
compile correctly. This speeds up configuration and building on windows.
🚧 Begin laying groundwork to backport MSVC_RUNTIME_LIBRARY
property
2019-09-28 10:47:15 -07:00
Tuan Anh Tran
b9b2aeecaf Custom precision (#300)
Fixes #285
2019-09-22 08:42:41 -07:00
Arseny Kapoulkine
6934b123d4 Move pugixml.rc to scripts/
This keeps src/ folder clean of auxiliary files only required for
special builds; note that CMakeLists.txt already depends on scripts/
(specifically for pkgconfig setup).
2019-09-21 09:21:13 -07:00
lady mesh
6fb765ca9d Add: Windows DLL version info header (#298)
Closes #294
2019-09-19 07:27:40 -07:00
Arseny Kapoulkine
6202519ca6 tests: Add memory safety tests for remove_children/attributes
The newly added tests make sure that during node/attribute destruction
we deallocate a few memory pages; this makes sure that we don't read
node data after it's being destroyed.

Also clean up formatting/style in the remove_* implementation a bit.
2019-09-17 20:34:40 -07:00
Tuan Anh Tran
fd7326fb91 feat: add remove_attributes() and remove_children() (#296)
These functions remove all attributes / child nodes in bulk which is faster than removing them one at a time.
2019-09-17 20:18:41 -07:00
Wolfgang Stöggl
ccb63a9186 Add LICENSE.md to RELEASE (#295) 2019-09-16 14:21:48 -07:00
Arseny Kapoulkine
5329ba03b5 scripts: Update NuGet package spec
Migrate from licenseUrl to license since licenseUrl is deprecated and
fix grammar for VS version list.
2019-09-15 17:56:15 -07:00
Arseny Kapoulkine
3c59df555b docs: Update documentation for 1.10 release
Update changelog and regenerate HTML documentation.
2019-09-11 21:51:02 -07:00
Arseny Kapoulkine
c6607740a0 Never escape > in attribute values
According to XML spec, > sometimes needs to be escaped in PCDATA (when
it occurs as a ]]> pattern), but it doesn't need to be escaped in
attribute values.

Contributes to #272.
2019-09-11 21:35:03 -07:00
Arseny Kapoulkine
946de603b1 Don't escape attribute quotation symbol
When using double quotes for attributes, we don't need to escape '; when
using single quotes, we don't need to escape ".

This changes behavior to match 1.9 by default (where we don't escape ').

Contributes to #272.
2019-09-11 21:27:20 -07:00
Arseny Kapoulkine
44e4d7e40b Update version to 1.10
Note: this chang also updates PUGIXML_VERSION macro to allow for
double-digit minor versions; this preserves the continuity of versions
so PUGIXML_VERSION >= 190 will still work.
2019-09-11 21:09:50 -07:00
Joel Andres Granados
84e322738b Update nuget creation to VS2019 (#291)
Create visual studio projects that are vs2019 compliant.
* nuget_build.ps1 :
Introduce a new argument that will define how we implement the nuget
build. For now we accept 201{9,7.5.3} as possible argument values.

* pugixml_vs2019{,_static}.vcxproj :
Add two visual studio projects that build pugi with the latest SDK and
build tools

* appveyor.yml
- Add Visual Studio 2019 to build targets
- Add Visual Studio 201{9,3,5} to build_scripts. And call
  nuget_build.ps1 with a new argument.
- Add Visual Studio 2019 to the test_scripts.
2019-09-09 07:37:29 -07:00
Wolfgang Stöggl
fdf0295753 Fix minor typos (#286)
- Typos were found by codespell v1.15.0
2019-08-21 07:46:11 -07:00
Arseny Kapoulkine
a556845555 tests: Work around test warnings in clang-7
Self-assignment generates a Wself-assign-overloaded warning.
2019-08-21 07:45:27 -07:00
Matan Nassau
4f6e7454fd fix cmake option USE_POSTFIX (#283)
appending the suffix to the build product need not be a function of
whether CMAKE_CONFIGURATION_TYPES is set.  for example, having two ninja
build trees---one for debug and another for release---is a fine use-case
for USE_POSTFIX.
2019-08-04 13:15:10 -07:00
Artur Leonov
c5752917c7 fix running tests (#280) 2019-07-25 19:14:39 -07:00
m-naumann
5a867cb1e3 Add support for using single quotes to enclose attribute values
This change adds format_attribute_single_quote flag that uses single quotes (`'`) instead of double quotes (`"`) for formatting attribute values.

Internal quotation marks are escaped using `&quot;` and `&apos;`.
2019-06-18 19:51:10 -07:00
Arseny Kapoulkine
fcb7c8d3e5
Merge pull request #276 from denchat/patch-1
std::random_shuffle is removed in current standard
2019-06-09 11:55:36 -07:00
denchat
86e0fe1980
Fix forgotten indentation 2019-06-10 00:35:17 +07:00
denchat
1312a46d91
std::random_shuffle is removed in current standard
use <random> 's generator and std::shuffle instead
2019-06-10 00:14:21 +07:00
Arseny Kapoulkine
7247a823b7 XPath: Add missing inline/PUGI__FN specifiers
Also split one-liner if/for loops for better readability and coverage.
2019-03-17 07:14:11 -07:00
Arseny Kapoulkine
cdd5d92f26
Merge pull request #265 from zeux/nocontrib
Remove contrib folder
2019-03-16 18:26:28 -07:00
Arseny Kapoulkine
29f3177d10 Remove contrib from Makefile and readme.txt 2019-03-13 23:17:23 -07:00
Arseny Kapoulkine
434c4a4d41 Remove contrib folder
This change removes contrib folder since it doesn't seem very useful;
Natvis scripts can and should go to scripts/ along with project files.

foreach.hpp is supporting a severely outdated BOOST_FOREACH construct;
in C++11 ranged for loop can be used with xml_node::children/attributes,
and BOOST_FOREACH can work with these as well.

foreach.hpp was also accidentally licensed as public domain which isn't
very helpful when the actual library is MIT. We could fix the license
but it seems better to just remove it.

Fixes #264.
2019-03-13 21:30:10 -07:00
Arseny Kapoulkine
8bf806c035 tests: Move control char tests to test_write.cpp
Also fix code style.
2019-03-09 06:58:07 -08:00
Arseny Kapoulkine
b01569918a docs: Regenerate HTML documentation
Includes wording fixes and format_skip_control_chars
2019-03-09 06:55:55 -08:00
Arseny Kapoulkine
b9a0d7ff23
Merge pull request #263 from Yanpas/fix_char_esc
format_skip_control_chars
2019-03-09 06:54:48 -08:00
Yan Pas
138976fd95 unit test and doc 2019-03-08 19:17:19 +03:00
Yan Pashkovsky
66e1b4e03e format_skip_control_chars 2019-03-07 17:54:30 +03:00
WheretIB
36e274d949 Visual Studio Natvis visualization for compact mode 2019-02-28 04:29:56 -08:00
Arseny Kapoulkine
12e8b699ce tests: Expand out-of-memory union tests
We now have two tests: one tests behavior when we run out of space when
appending the node set (in which case the append fails), another one
tests behavior when we run out of space when filtering the node set (in
which case the set still contains redundant data).
2019-02-26 23:57:58 -08:00
Arseny Kapoulkine
c55ea3bc1e XPath: Make remove_duplicates generate stable order
Given an unsorted sequence, remove_duplicates would sort it using the
pointer value of attributes/nodes and then remove consecutive
duplicates.

This was problematic because it meant that the result of XPath queries
was dependent on the memory allocation pattern. While it's technically
incorrect to rely on the order, this results in easy to miss bugs.

This is particularly common when XPath queries use union operators -
although we also will call remove_duplicates in other cases.

This change reworks the code to use a hash set instead, using the same
hash function we use for compact storage. To make sure it performs well,
we allocate enough buckets for count * 1.5 (assuming all elements are
unique); since each bucket is a single pointer unlike xpath_node which
is two pointers, we need somewhere between size * 0.75 and size * 1.5
temporary storage.

The resulting filtering is stable - we remove elements that we have seen
before but we don't change the order - and is actually significantly
faster than sorting was.

With a large union operation, before this change it took ~56 ms per 100
query invocations to remove duplicates, and after this change it takes
~20ms.

Fixes #254.
2019-02-26 23:57:58 -08:00
Arseny Kapoulkine
930a701f1f tests: Disable flaky test
This test is very sensitive to the particular implementation of union
aggregation; for now lets disable this.

We need a more robust way to test union allocation failures.
2019-02-26 22:15:34 -08:00
Arseny Kapoulkine
93c7bacb29 XPath: Create set for a|b in order before duplicate filtering
This does not change the result of a union operation [substantially], but
it means that we now give a list to remove_duplicates that has more natural
ordering.

If remove_duplicates didn't sort the array, we'd have union operations
resulting in a consistent predictable order.

Contributes to #254.
2019-02-26 21:39:52 -08:00
Arseny Kapoulkine
d902709da2 Refactor CMakeLists.txt support for multiple targets
We now have a ${LIBRARY} variable that we can either use directly or in
a foreach loop to be able to process either pugixml or pugixml-static
and pugixml-shared targets.

Also fixes incorrect shared library assignment when
BUILD_SHARED_AND_STATIC_LIBS is defined, and only links the static
library in for make check.
2019-02-06 08:15:27 -08:00
basti171
1d59e4d9d8 make pugixml build static and shared via cmake (#257) 2019-02-06 07:39:23 -08:00
Arseny Kapoulkine
160c1c23d9
docs: Improve null node comparison wording
Change confusing wording: null nodes compare as equal to null handles, the previous wording implied that each null handle is unique
2019-01-25 16:42:25 -08:00
Arseny Kapoulkine
b67ef29c08 docs: Draw attention to the fact that you have to compile pugixml.cpp
This may or may not make it more clear that pugixml.cpp has to be
compiled - either as one of the projects or as a standalone project via
CMake et al - for it to work by default.

Fixes #256.
2019-01-19 18:25:25 -08:00
Arseny Kapoulkine
9fcae40bb5 Happy New Year! 2019-01-01 23:05:04 +03:00
Millian Poquet
b3db08ffcc pkg-config: Use CMake GnuInstallDirs FULL vars
Fixes an installation problem in Nix packages, as non-FULL variables are
already absolute paths in this case.
2018-12-10 11:12:36 -08:00
Arseny Kapoulkine
ba84465d2e Move unreachable line handling to Makefile
This allows us to reuse this code for MinGW builds.

Additionally disable coverage step for Linux clang - it looks like
Travis has a mismatch in the version of gcov info between clang and gcov
which causes gcov to crash - somehow this crash isn't picked up as a
build error.
2018-12-10 11:12:13 -08:00
Arseny Kapoulkine
2da1524977 Add PUGIXML_WCHAR_MODE configuration to MinGW tests
We are currently only testing UTF8 mode which means we don't have code
coverage for some UTF->UTF decoding paths.
2018-12-09 17:20:02 -08:00
Arseny Kapoulkine
7d0d8ee79f Update .travis.yml
This is a dummy commit to trigger codecov build
2018-12-09 16:31:22 -08:00
Arseny Kapoulkine
4b57d09882 Add support for MinGW builds on AppVeyor
Use cygwin to build coverage build and upload coverage data to codecov.
2018-12-09 16:16:59 -08:00
Arseny Kapoulkine
7664bbf9af tests: Only use load_file_special_folder test on macOS
The behavior on Linux is very different between kernel versions, and it
triggers an unexpected OOM during sanitizer runs because somehow the
size is reported to be LONG_MAX. It's not clear that it helps us cover
any paths we don't cover otherwise - it would be nice to be able to test
failing to load a multi-gigabyte file on a 32-bit system, but we can't
do this easily atm anyway.
2018-11-27 08:07:31 -08:00
Arseny Kapoulkine
1a9c3f66db Enable config=sanitize in Travis CI
This commit changes sanitize configuration to fail on the first error
and ignore floating-point division and overflow "errors" that trigger
when we test the corresponding functionality. This makes it possible to
run this on all commits - if new UB or memory safety issues are introduced,
asan/ubsan will catch them.
2018-11-27 08:07:31 -08:00
Arseny Kapoulkine
f9a2a7d19e Fix Wdouble-promotion warnings
We had a few places in test code and library source where we used an
implicit float->double cast; while it should preserve the value exactly,
gcc/clang implement this warning to make sure uses of double are intentional.

This change also adds the warning to Makefile to make sure we don't
regress on this warning.

Fixes #243.
2018-11-23 23:39:22 -08:00
Arseny Kapoulkine
aac75cd299 Escape TAB character in attribute values with &#09;
This change modifies the table entries for ctx_special_attr to treat TAB
character as special, which makes the output code escape it.

Before this change, trying to use TAB in an attribute value would output
it verbatim; during subsequent parsing, pugixml - and other compliant
parsers - would apply attribute-value normalization, turning the TAB
into a space and losing the original value.

Using &#09; fixes this; if an input document has &#09; in an attribute
value, that gets unescaped into \t during parsing and escaped back into
&#09; during output, which means we can now roundtrip values like this.

Fixes #242.
2018-11-19 22:26:21 -08:00
cecilios
7d2436ec2f Add coverity annotations 2018-11-16 15:25:12 -08:00
Arseny Kapoulkine
fa686f004a Update all URLs to pugixml.org to https:// 2018-11-12 12:28:54 -08:00
Wolfgang Stöggl
d3dd79d54d Update URL to https in pugixml.pc.in 2018-11-12 07:49:54 -08:00
Arseny Kapoulkine
d9fadc7464 XPath: Workaround Coverity false positive
Coverity hits a similar false positive to what clang static analyzer hit
- it assumes that since optimize() checks _right for being nullptr,
optimize_self() might hit _right=nullptr in the ast_op_equal case which
is impossible.

Contributes to #236.
2018-10-23 21:40:18 -07:00
Dan Lipsa
273fa0ab26 Remove warning in Visual Studio (#235)
The following warning is removed:
Visual Studio 14.0
1. warning C4275: non dll-interface class 'std::exception' used as
   base for dll-interface class 'vtkpugixml::xpath_exception'
2018-10-16 08:43:32 -07:00
Arseny Kapoulkine
81c82588bd Work around clang --analyze warnings
clang doesn't understand the invariants guaranteed for specific AST node
types and, when seeing null pointer checks in optimize(), assumes any
pointers in the node might be null. Work around this by adding explicit
- redundant - null pointer checks.
2018-09-24 20:38:09 -07:00
Arseny Kapoulkine
e3b5e9ce3c XPath: Refactor xpath_node_set short buffer optimization
This change replaces xpath_node_set single element storage with a
single-element array in hopes that this would silence Coverity false
positive about getting a singleton pointer.

Additionally, it refactors _assign member to unify small and large
buffer codepaths since they are basically identical.

Fixes #233 (hopefully)
2018-09-24 20:19:31 -07:00
Arseny Kapoulkine
1a96777b11 tests: Fix XPath denorm tests on Intel compiler
Intel compiler by default sets flush-to-zero flags which causes our
denorm test to produce 0.0. So make sure that denorms work on FPU before
testing the string output.

Fixes #218.
2018-08-13 22:06:57 -07:00
Arseny Kapoulkine
cb4a74d5e5 Minor CMakeLists.txt cleanup
Instead of hardcoding SOVERSION, use CMake variables to set it up.

Closes #220.
2018-08-13 21:38:44 -07:00
Vyacheslav Egorov
c51214f21e Visual Studio Natvis visualization (#227)
* Visual Studio Natvis visualization

* Changed string format to remove separate natvis file for wide character mode

* Display any node type with name and value if any of them are available
2018-08-07 17:03:37 -07:00
Arseny Kapoulkine
6b9c07e6ed tests: Allow document_load_file_special_folder to load empty document
On some Debian systems it looks like we *can* open the current folder as
a file and read its contents, but parsing the result produces an empty
document. We now handle this case as well.

Fixes #225.
2018-07-30 07:32:09 -07:00
Arseny Kapoulkine
514478d1f8 Fix version comment; 190 = 1.9.0 (major.minor.patch)
Fixes #224.
2018-07-28 08:08:45 -07:00
Arseny Kapoulkine
f3139f4c04 Add .gitattributes file
This makes sure the contents of tests/data/ folder does not go through
newline conversion, which breaks tests that rely on some files having LF
and some files having CR+LF.

Fixes #222.
2018-07-23 23:13:02 -07:00
Arseny Kapoulkine
699143c5d4 scripts: Set file permissions when building .zip archive
It looks like zipfile module by default uses the permission mask 0,
which after unpacking on Unix-based systems leads to the files being
inaccessible.

We now explicitly set file mask to rw-r--r-- to match .tar.gz defaults.

Fixes #217.
2018-07-22 18:57:10 -07:00
Wolfgang Stöggl
c12889f7cc Use CMAKE_INSTALL_LIBDIR for pugixml.pc (#215)
- Up to now, the libdir was hardcoded to "lib" inside pugixml.pc and
  the install directory of pugixml.pc was "lib/pkgconfig"
- Adds support for lib and lib64 by using CMAKE_INSTALL_LIBDIR variable
2018-06-26 15:53:42 -07:00
Bernd Amend
12139f587b fix cmake warning "Policy CMP0048 is not set" (#214)
This also bumps the minimum CMake version to 3.0 (from 2.8.12).
2018-06-20 07:55:14 -07:00
Arseny Kapoulkine
e584ea337e docs: Mention that node is a container of children in ranged for section
This is implicitly true due to the following section, but that was
written before C++11 so this does deserve a special mention in ranged
for section as well.

Fixes #210.
2018-05-17 08:04:47 -07:00
Arseny Kapoulkine
51322cffa1 Move CMake build postfix setup behind an off-by-default USE_POSTFIX
This setup can interfere with existing workflows in two ways:

- If the target application used CMake and configured custom postfixes,
this change would override them

- If the target application did *not* use CMake, it'd have to abide by
these conventions even if the target configuration used is unexpected -
for example, the default "preferred" configuration is frequently
RelWithDebugInfo, not Release, which now has a postfix.

Fixes #198.
2018-04-27 08:13:08 -07:00
Arseny Kapoulkine
c53fdab93a Clarify comment in get_strconv_pcdata as well 2018-04-14 23:45:23 -07:00
Arseny Kapoulkine
43b0a6a0a3 Clarify comment in get_strconv_attribute
This might have helped a bit with confusion in #195.
2018-04-14 23:27:59 -07:00
Arseny Kapoulkine
24a7064e57
Update README.md
Add example code
2018-04-12 10:07:26 -07:00
Arseny Kapoulkine
e6dde9cf69 scripts: Use LICENSE file in pugixml.podspec
We no longer need to specify the license boilerplate verbatim since we
have a separate file.
2018-04-12 07:09:14 -07:00
Alexander Straub
4c791586ee Suffixes for different build types (#191) 2018-04-11 08:13:50 -07:00
Arseny Kapoulkine
552773269e Add brief license information back to README.md
Also rename LICENSE to LICENSE.md
2018-04-11 08:12:34 -07:00
Bruno Pagani
61f2180d0f Split LICENSE to a separate file for easier distribution
Also fix two http → https occurrences.
2018-04-11 08:12:34 -07:00
Eli Schwartz
daeb8013b2 cmake: always install the pkg-config file (#193)
There's really never a reason to *not* want this installed. If an option
is needed to specify installing in a versioned subdirectory, this option
should be explicitly described rather than hidden in something else.

As an added bonus, this makes the CMake install code slightly *less*
complicated.
2018-04-09 10:48:53 -07:00
Arseny Kapoulkine
341cea5a32 docs: Fix changelog formatting 2018-04-04 08:26:21 -07:00
Arseny Kapoulkine
8436f2a69b tests: Fix PUGIXML_COMPACT build on some platforms
We need bad_alloc that lives in <new>, not <exception>.
2018-04-04 07:53:16 -07:00
Arseny Kapoulkine
474a4a3f73 tests: Fix PUGIXML_NO_XPATH,PUGIXML_COMPACT build
pugixml.hpp wasn't including the <exception> header in this build but
test code needed it.
2018-04-03 21:56:09 -07:00
Arseny Kapoulkine
5f4afe3bd2 tests: Fix PUGIXML_NO_XPATH build 2018-04-03 21:51:41 -07:00
Arseny Kapoulkine
62728d9c2e tests: Fix PUGIXML_NO_EXCEPTIONS tests 2018-04-02 21:51:04 -07:00
Arseny Kapoulkine
be260a09c1 docs: Regenerate HTML documentation 2018-04-02 21:46:57 -07:00
Arseny Kapoulkine
0c74e117b8 Update version to 1.9 2018-04-02 21:46:14 -07:00
Arseny Kapoulkine
a32585286a tests: Fix PUGIXML_NO_STL build 2018-04-02 21:33:03 -07:00
Arseny Kapoulkine
cff1933ec9 docs: Update changelog 2018-04-02 21:07:58 -07:00
Arseny Kapoulkine
4f9af79850 Work around gcc-8 warning
gcc-8 produces "attribute directive ignored" warning for
no_sanitize("unsigned-integer-overflow"); at some point gcc will
introduce integer sanitizer support and we'll have to do this all over
again but for now just don't emit the attribute.
2018-04-02 21:06:32 -07:00
Arseny Kapoulkine
cb0e8937da docs: Update v1.9 release date to 04.04 2018-04-02 19:15:23 -07:00
Arseny Kapoulkine
951f1ed4ed Add a comment to clarify subtle branch in node_copy_tree 2018-03-29 08:27:56 -07:00
Arseny Kapoulkine
cec32da2b5 docs: Update changelog
Mention ubsan fixes; these fixes probably fix compact mode on some
64-bit architecture where unaligned pointer reads aren't valid as well
but it's probably not very relevant...
2018-03-16 21:34:56 -07:00
Arseny Kapoulkine
fe7b837868 tests: Fix PUGIXML_COMPACT+PUGIXML_WCHAR_MODE tests
Several tests got the buffer size wrong when sizeof(char_t)>1, and one
test didn't meet the carefully tuned allocation criteria under compact
mode due to the hash table usage and had to be changed a bit.
2018-03-16 21:33:26 -07:00
Arseny Kapoulkine
e50672cf37 ubsan: Fix undefined behavior for signed left shift in compact mode
We were using << compact_alignment_log2 instead of * compact_alignment
for symmetry with the encoding where >> is crucial to keep code fast and
round to negative infinity.

For decoding, the results are the same and any reasonable compiler
should convert *4 into <<2 so just use a multiplication - that doesn't
trigger UB on negative numbers.
2018-03-16 21:25:12 -07:00
Arseny Kapoulkine
9540016f6d ubsan: Fix type mismatch for xml_extra_buffer in compact mode
We were using allocate_memory to allocate struct xml_extra_buffer that
contains pointers; with compact mode, this allocation can be misaligned
by 4b with 8b pointers; fix this by manually realigning the pointer.
2018-03-15 23:10:10 -07:00
Arseny Kapoulkine
15fdb838c7 ubsan: Fix type mismatch in compact mode for document data
We were misaligning document data on 64-bit platforms by placing 8b
pointers at 4b offsets; fix this by reserving a full pointer worth of
bytes for page marker.
2018-03-15 23:09:35 -07:00
Arseny Kapoulkine
951c8f15d2 Refactor noexcept macros
Define noexcept using _MSC_VER instead of _MSC_FULL_VER (first release
of MSVC 2015 should have it), remove redundant PUGIXML_HAS_NOEXCEPT and
define PUGIXML_NOEXCEPT_IF_NOT_COMPACT in terms of PUGIXML_NOEXCEPT.
2018-03-15 22:31:13 -07:00
Arseny Kapoulkine
655bc825a1 docs: Add preliminary 1.9 changelog
Still trying to decide if the next version should be 1.9 or 1.8x and
what other changes need to go in.
2018-03-12 19:00:31 -07:00
Matthäus Brandl
9187e6500c Adds noexcept specifiers to the move special members of xml_document,… (#185)
* Adds noexcept specifiers to the move special members of xml_document, but only #ifndef PUGIXML_COMPACT
2018-03-03 10:19:37 -08:00
Matthäus Brandl
8284dbf61d Add noexcept specifiers to move special members where possible (#183)
* Adds a macro definition to be able to use noexcept with supporting compilers

* Adds noexcept specifier to move special members of xpath_node_set, xpath_variable_set and xpath_query, but not of xml_document as it has a throwing implementation
2018-03-01 20:13:43 -08:00
Arseny Kapoulkine
41219a5a20
Merge pull request #184 from brandl-muc/override_for_msvc
Enables usage of override specifier for MSVC compilers
2018-02-27 14:22:52 -08:00
Brandl, Matthäus (MBR)
b8d1d07ad8 Enables usage of override specifier for MSVC compilers (beginning with 17.0 which is the compiler of Visual Studio 2012) 2018-02-27 22:27:15 +01:00
Arseny Kapoulkine
b127cfb18e Fix Texas Instruments compiler warning
Texas Instruments compiler produces this warning for unused template
member functions:

	"pugixml.cpp", line 253: warning #179-D: function
	"pugi::impl::<unnamed>::auto_deleter<T>::release [with
	T=pugi::impl::<unnamed>::xml_stream_chunk<char>]" was declared but
	never referenced

As far as I can tell, this is a compiler issue - these functions should
not be instantiated in the first place; while it's possible to rework
the code to work around this, the changes would be fragile. It seems
best to just disable this warning - we've seen something similar on SNC
(which appears to use the same frontend!..).

Fixes #182.
2018-02-27 08:49:16 -08:00
Arseny Kapoulkine
2ec3579f29 Work around gcc issues with limits.h not defining LLONG_MIN
It looks like there are several cases where this might happen:

- In some MinGW distributions, the LLONG_MIN/etc defines are guarded
with:

	#if !defined(__STRICT_ANSI__) && defined(__GNUC__)

Which means that you don't get them in strict ANSI mode. The previous
workaround was specifically targeted towards this.

- In some GCC distributions (notably GCC 6.3.0 in some configurations),
LLONG_MIN/etc. defines are guarded with:

	#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)

But __STDC_VERSION__ isn't defined as C99 even if you use -std=c++14 -
which is probably technically valid, but not useful.

To work around this, redefine the symbols whenever we are building with
GCC and we need them and they aren't defined - doing this is better than
not building. Instead of hard-coding the constants, use GCC-specific
__LONG_LONG_MAX__ to compute them.

Fixes #181.
2018-02-22 08:15:53 -08:00
Arseny Kapoulkine
9bb468b3a9
Merge pull request #179 from mathstuf/cmake-touchups
Cmake touchups
2018-01-29 11:11:23 -08:00
Ben Boeckel
7fcfb72dcd cmake: keep sources and headers separate 2018-01-29 13:50:31 -05:00
Ben Boeckel
0df7adb680 cmake: set the minimum version before the project call 2018-01-29 13:50:30 -05:00
Arseny Kapoulkine
195494186e build: Add clang/Linux builds to Travis 2018-01-23 07:58:21 -08:00
Arseny Kapoulkine
3f28a5d97a Update all copyright notices to specify year 2018 2018-01-07 20:28:42 -08:00
Arseny Kapoulkine
f360842d48 docs: Fix a typo in dom_tree.png
<mesh> node attribute name is "name", not "mesh".
2017-12-29 17:03:54 -08:00
Arseny Kapoulkine
c2266d7a60
Merge pull request #177 from zeux/osx-fix
tests: Fix OSX test failure
2017-12-22 12:24:44 -08:00
Arseny Kapoulkine
a55f575a03 tests: Fix OSX test failure
Apparently at some point OSX behavior when reading /dev/tty switched
from "can't open the file" to "the file can be opened and 0 bytes can be
read from it" which generates a wrong error and doesn't exercise the
code path we care about.
2017-12-22 11:30:15 -08:00
Arseny Kapoulkine
cb7b78b039 docs: Fixed quickstart links
Fixes #176.
2017-12-22 10:40:42 -08:00
Arseny Kapoulkine
257fbb4e1b Use raw pointers in xml_node::traverse implementation
This makes it a bit faster and matches other internal code better.
2017-11-13 19:29:42 -08:00
Arseny Kapoulkine
344c74a74c XPath: Always allocate xpath_strings on temporary stack for concat
The static_buffer optimization seems to come from the time where the
on-heap buffer was allocated using global memory operations. At this
point the temporary buffer and temporary string storage all come from
the evaluation stack (that can be partially allocated on heap...), so
the extra logic isn't relevant for performance.
2017-11-13 19:10:36 -08:00
Arseny Kapoulkine
7c6d0010b3
Merge pull request #170 from zeux/move
This change implements move ctor and assign support for xml_document.

All node handles remain valid after the move and point to the new document; the only exception is the document node itself (that remains unmoved).

Move is O(document size) in theory because it needs to relocate immediate document children (there is just one in conformant documents) and all memory pages; in practice the memory pages only need the header adjusted, which is ~0.1% of the actual data size.

Move requires no allocations in general, except when using compact mode where some moves need to grow the hash table which can fail (throw).

Fixes #104
2017-11-13 13:24:43 -08:00
Arseny Kapoulkine
3860b5076f Fix -Wshadow warning 2017-11-13 09:27:38 -08:00
Arseny Kapoulkine
58611c8702 tests: Add compact move tests
This helps make sure our error handling logic works and is exercised.
2017-11-13 08:59:16 -08:00
Arseny Kapoulkine
4bd8771c2f Implement correct move error handling for compact mode
In compact mode, we currently can not support zero-allocation moves
since some pointer assignments required during the move need to allocate
hash table slots.

This is mostly applicable to xml_document_struct::first_child, since the
pointer to this element is used as a hash table key, but there are some
contrived cases where parents of root's children need a hash slot and
didn't have it before.

These cases can be fixed by changing the compact encoding to be a bit
more move friendly, but for now it's easier to handle the error and
throw/return during move.

When this happens, the source document doesn't change.
2017-11-13 08:57:16 -08:00
Arseny Kapoulkine
91a3c28862 Add count argument to compact_hash_table::rehash/reserve
This allows us to do a single reserve for a known amount of assignments
that is larger than the default minimum per reserve (16).
2017-11-13 08:37:34 -08:00
Arseny Kapoulkine
6016e2180e CMake: Add __declspec(dllexport) for shared library builds
This makes sure that MSVC shared library build actually exports all the
needed symbols and generates import table.

Somehow, this is actually enough to make pugixml link as a DLL - there's
no need to specify __declspec(dllimport) even though pugixml exports
classes via DLL.

Fixes #113.
2017-11-12 20:21:46 -08:00
Arseny Kapoulkine
492ebc22bc tests: Fix expansion-to-defined warning
This warning is new as of GCC 7 and highlights undefined behavior in the
preprocessor that ASAN detection was relying on.
2017-11-10 21:35:59 -08:00
Arseny Kapoulkine
6fe31d1477 build: Simplify config=sanitize
These days OSX clang supports UB sanitizer so we can just use the same
settings for all systems.
2017-10-29 21:24:04 -07:00
Arseny Kapoulkine
ba9504325e build: Switch fuzz builds to use Clang 5.0 sanitize=fuzzer
The old fuzzer location is deprecated; this also makes it almost trivial
to fuzz, provided that the clang is set up correctly... on Ubuntu 17.10,
a command sequence like this works now:

    sudo apt install clang-5.0
    sudo apt install libfuzzer-5.0
    sudo cp /usr/lib/llvm-5.0/lib/libFuzzer.a /usr/lib/libLLVMFuzzer.a
    CXX=clang++-5.0 make fuzz_parse
2017-10-29 19:54:48 -07:00
Arseny Kapoulkine
0504fa4e90 tests: Add more tests for document move
These tests currently fail for compact mode because of ->reserve()
failing.
2017-10-26 08:36:05 -07:00
Arseny Kapoulkine
3af93a39d7 Clarify a note about compact hash behavior during move
After move some nodes in the hash table can have keys that point to
other; this makes the table somewhat larger but this does not impact
correctness.

The reason is that for us to access a key in the hash table, there
should be a compact_pointer/string object with the state indicating that
it is stored in a hash table, and with the address matching the key. For
this to happen, we had to have put this object into this state which
would mean that we'd overwrite the hash entry with the new, correct
value.

When nodes/pages are being removed, we do not clean up keys from the
hash table - it's safe for the same reason, and thus move doesn't
introduce additional contracts here.
2017-10-20 21:57:14 -07:00
Arseny Kapoulkine
b0fc587a7f tests: Add more move tests
We now check that appending a child to a moved document performs no
allocations - this is already the case, but if we neglected to copy the
allocator state this test would fail.
2017-10-20 21:53:42 -07:00
Arseny Kapoulkine
50bc0d5a69 tests: Adjust move coverage tests
Large test wasn't testing shared parent condition properly - add one
more level of hierarchy so that it works as expected.
2017-09-25 22:54:42 -07:00
Arseny Kapoulkine
26ead385a7 tests: Add more move tests
Add a test that checks that static buffer pointer was moved correctly
by checking if offset_debug still works.
2017-09-25 22:52:26 -07:00
Arseny Kapoulkine
402b967fa9 tests: Add more move tests
Make sure we have coverage for empty documents and for large documents
that trigger compact_shared_parent != root for some pages.
2017-09-25 22:47:10 -07:00
Arseny Kapoulkine
faba4786c0 tests: Add more document move tests
Verify that move doesn't allocate and that it preserves structures
required for tree memory management and append_buffer in tact.
2017-09-25 22:38:30 -07:00
Arseny Kapoulkine
febf25d1af Fix -Wshadow warning 2017-09-25 21:48:37 -07:00
Arseny Kapoulkine
6eb7519dba tests: Add basic move tests
These just verify that move ctor/assignment operator work as expected in
simple cases - there are a number of ways in which the internal
structure can be incorrect...
2017-09-25 21:37:56 -07:00
Arseny Kapoulkine
a567f12d76 Implement move support for xml_document
This change implements the initial version of move construction and
assignment support for documents.

When moving a document to another document, we always make sure move
target is in "clean" state (empty document), and proceed by relocating
all structures in the most efficient way possible.

Complications arise from the fact that the root (document) node is
embedded into xml_document object, so all pointers to it have to change;
this includes parent pointers of all first-level children as well as
allocator pointers in all memory pages and previous pointer in the first
on-heap memory page.

Additionally, compact mode makes everything even more complicated
because some of the pointers we need to update are stored in the hash
table (in fact, document first_child pointer is very likely to be there;
some parent pointers in first-level children will be using
compact_shared_parent but some won't be) which requires allocating a new
hash table which can fail.

Some details of this process are not fully fleshed out, especially for
compact mode; and this definitely requires many tests.
2017-09-25 19:31:18 -07:00
Arseny Kapoulkine
a569e6a737 Switch to sudo=false Travis env 2017-09-24 22:46:48 -07:00
Arseny Kapoulkine
900a1cc943 docs: Clarify Unicode validation behavior
It has always been the case that pugixml does not perform Unicode
validation or name/tag Unicode character class validation, but it wasn't
very obvious from documentation.

Fixes #162
2017-08-29 20:46:30 -07:00
Arseny Kapoulkine
4f2ad720c8 docs: Update encoding conversion description
We support Latin-1 and automatically detect it by parsing the encoding
from document declaration; both of these were omitted from the
description of the automatic detection.

Additionally, the description has been rewritten to be more concise and
a bit more abstract - there's no need to specify the algorithm precisely
here.

Fixes #158.
2017-08-21 20:54:38 -07:00
Arseny Kapoulkine
50952c0a5e scripts: Fix NuGet VS2017 build
Due to a typo in build script v141 binaries were built using VS2015
instead of VS2017.

Fixes #157.
2017-08-20 07:12:09 +01:00
Arseny Kapoulkine
f423cec11b scripts: Disable LTCG for VS2017
Using LTCG restricts the resulting .lib files to a specific compiler
version, causing version conflicts when the compiler gets updated
without changing the toolset version. VS2017 now has two incompatible
compilers, 15.0 and 15.3, both of which use toolset v141...
2017-08-18 21:44:47 +01:00
Arseny Kapoulkine
77d7e60379 Fix Clang/C2 compatibility
Clang/C2 does not implement __builtin_expect; additionally we need to
work around deprecation warnings for fopen by disabling them.
2017-07-17 22:15:35 -07:00
Arseny Kapoulkine
ed86ef32b3 Update README.md
Switch codecov.io URLs to https
2017-06-29 01:03:55 -07:00
Arseny Kapoulkine
cfa64676be Update README.md 2017-06-29 00:53:59 -07:00
Arseny Kapoulkine
f3e0f4249c tests: Add more stream coverage tests
These new tests test that tellg() can fail when being called the second
time, which leads to seekable implementation failing.
2017-06-23 08:44:52 -07:00
Arseny Kapoulkine
4564d31c76 tests: Add stream coverage tests
These tests simulate various error conditions when reading data from
streams - seeks failing in seekable streams, underflow throwing an
exception causing read to set badbit, etc.

This change also adjusts memory thresholds to cause a reliable out of
memory during construction of a final buffer for non-seekable streams.
2017-06-23 07:48:09 -07:00
Arseny Kapoulkine
20a8eced3b tests: Fix PUGIXML_WCHAR_MODE build 2017-06-22 22:18:16 -07:00
Arseny Kapoulkine
3870217381 tests: Add more XPath out of memory tests
This fixes missing coverage in translate_table_generate and
xpath_node_set_raw::append.
2017-06-22 22:11:43 -07:00
Arseny Kapoulkine
5867aff943 tests: Make using namespace more explicit
Hiding using namespace in common.hpp is somewhat surprising so remove
common.hpp and move using namespace into all .cpp files that need it.
2017-06-22 20:41:08 -07:00
Arseny Kapoulkine
4b371e10ee tests: Remove redundant pugi:: qualifier
Most tests have `using namespace pugi` which makes explicit
qualifications unnecessary.
2017-06-22 20:33:02 -07:00
Arseny Kapoulkine
853333cd70 Use PUGI__MSVC_CRT_VERSION instead of _MSC_VER
It's not clear whether we still need PUGI__MSVC_CRT_VERSION, but it's
more consistent for now to use it for _snprintf_s since this is relying
on a CRT extension, not on a compiler feature.
2017-06-22 20:28:06 -07:00
Arseny Kapoulkine
2252927c04 Deprecate xml_document::load(const char*) and xml_node::select_single_node
These functions were deprecated via comments in 1.5 but never got the
deprecated attribute; now is the time!

Using deprecated functions produces a warning; to silence it, this
change moves the relevant tests to a separate translation unit that has
deprecation disabled.
2017-06-22 09:13:10 -07:00
Arseny Kapoulkine
94ef7b3a03 Merge pull request #151 from zeux/nuget
Rework NuGet package building
2017-06-20 21:32:11 -07:00
Arseny Kapoulkine
88d43a7ebc scripts: Refactor nuget_build.ps1
Unify build paths in all MSBuild VS projects and extract common build
logic into functions.

Note that this change changes both VS2010 and VS2013 projects to have
more predictable output paths and fixed output file name (pugixml).
2017-06-20 21:11:35 -07:00
Arseny Kapoulkine
fbc7085c14 scripts: Clarify the linkage settings in package description
Also improve linkage description
2017-06-20 21:11:35 -07:00
Arseny Kapoulkine
d2b0328198 Remove CoApp msi installation
We build NuGet package manually now so we don't need CoApp.
2017-06-20 21:11:35 -07:00
Arseny Kapoulkine
7d651ac3b6 Update .gitignore 2017-06-20 21:11:35 -07:00
Arseny Kapoulkine
a7c4070df7 scripts: Switch to manual NuGet package with both CRT linkages
We'd like to build pugixml with both static & dynamic CRT and put it
all in one NuGet package.

CoApp sort of allows us to do this via dynamic/static pivots, but it
does not let us customize the names of the pivots and additionally has
some bugs with the project setup. Their project modifications are also
much more complicated - really, at this point we should do this
ourselves.

Create a simple native NuGet package with Linkage setting that picks the
right library, and package all libraries appropriately. Note that we use
the unified path syntax to make it simple to just get the right .lib
file from the toolset/platform/configuration/linkage combo.
2017-06-20 21:11:35 -07:00
Arseny Kapoulkine
208e2cf043 Change PUGI__SNPRINTF to use _countof for MSVC
The macro only works correctly when the input argument is an array with
a statically known size - pointers or arrays decayed to pointers won't
work silently.

While this is unlikely to surface issues that aren't caught in
tests/code review, use _countof for MSVC to prevent such code from
compiling.
2017-06-19 07:06:47 -07:00
Arseny Kapoulkine
867bd2583b Merge pull request #150 from zeux/nuget
Add VS2017 to AppVeyor test run
2017-06-18 22:34:08 -07:00
Arseny Kapoulkine
9357837d2e Add VS2017 to AppVeyor test run
This requires moving the list of VS versions out of
autotest-appveyor.ps1 and into appveyor.yml.
2017-06-18 22:20:13 -07:00
Arseny Kapoulkine
7418bd0d79 scripts: Cleanup nuget_build.ps1
Correctly check for error codes and don't run .bat file since it doesn't
work anyway (the variables it sets aren't accessible in PowerShell, and
the path to the script doesn't seem to be the same in VS2017).
2017-06-18 21:11:54 -07:00
Arseny Kapoulkine
ade869ea58 Merge pull request #147 from igagis/master
VS2017 project + NuGet support
2017-06-18 20:49:11 -07:00
Arseny Kapoulkine
0027b6ac79 tests: Improve XPath coverage
Add memory allocation failure test for concact with a very large list
and make sure we have every single axis covered with and without a
predicate, with and without a previous step.
2017-06-16 22:45:42 -07:00
Arseny Kapoulkine
08f102f14c tests: Add even more stream coverage tests
Apparently only narrow character streams had out of memory coverage -
fix that and also split this into a separate test.
2017-06-16 21:38:55 -07:00
Arseny Kapoulkine
86593c0999 tests: Add more stream coverage tests
Cover both char and wchar_t stream loading in a single run instead of
using pugi::char_t.
2017-06-16 17:08:00 -07:00
Arseny Kapoulkine
3aa2b40354 tests: Add more coverage tests for stream loading
Cover more failure cases and simplify the streambuf implementation a
bit.
2017-06-16 16:41:08 -07:00
Arseny Kapoulkine
b6995f06b9 Fix BorlandC compilation
Rename partition to partition3 to resolve conflicts with std::partition.
2017-06-16 00:32:01 -07:00
Arseny Kapoulkine
bd23216420 tests: Improve XPath test coverage
Add more memory allocation failure tests.
2017-06-16 00:29:14 -07:00
Arseny Kapoulkine
a3664ea971 tests: Expand write_flush coverage
Adjust the buffer size to be right on the edge of the overflow, make
sure we actually output &quot; instead of ".
2017-06-16 00:09:32 -07:00
Arseny Kapoulkine
d2892be902 tests: Add xml_buffered_writer coverage test
This test triggers flush() condition for each optimized write() method.
2017-06-15 23:52:56 -07:00
Arseny Kapoulkine
95f013ba80 Refactor snprintf support
Instead of branching code at each invocation site, use variadic macros
to create a wrapping macro that use snprintf for the buffer of a
statically known size.

Variadic macros are supported by all C++11 compilers, as is snprintf;
on MSVC 2005+ we don't necessarily have snprintf, but we can use
_snprintf_s with _TRUNCATE to get the same behavior. In all other cases
we fall back to sprintf, that (theoretically) can lead to a stack buffer
overflow.

In practice all snprintfs used in pugixml use buffers that should be
large enough to never be overflown but snprintf is safe even if this is
not the case.
2017-06-15 23:35:20 -07:00
Arseny Kapoulkine
207bc788e9 Use buffer with a static size in convert_number_to_mantissa_exponent
We use references to arrays elsewhere in the codebase and there's just
one caller for this function so it's easier to fix the size.

This will simplify snprintf refactoring.
2017-06-15 22:58:46 -07:00
Arseny Kapoulkine
cd2804d3ee Merge pull request #145 from noresources/snprintf
use snprintf instead of sprintf
2017-06-15 21:34:04 -07:00
Arseny Kapoulkine
0698810abb Merge pull request #149 from zeux/test-path
Improve code coverage
2017-06-15 21:17:26 -07:00
Arseny Kapoulkine
927d321d90 Exclude unreachable lines from code coverage
codecov.io does not seem to support lcov regex customization;
additionally, we can't just replace unreachable with LCOV_LINE_EXCL
in gcov file - so we have to patch the ##### indicator (which suggests
the line hasn't been hit) with 1.

See also https://github.com/codecov/support/issues/144
2017-06-15 20:58:26 -07:00
Arseny Kapoulkine
b3b44841f0 Mark all assert(false) statements as unreachable
Now we can exclude these from code coverage since it's logically
impossible to hit them in tests.
2017-06-15 09:26:23 -07:00
Arseny Kapoulkine
c40fd364ce tests: Add tests for loading special files
New tests try to load a folder as an XML document, and a device. Both
are intended to exercise some otherwise non-hittable error paths in
load_file implementation.
2017-06-15 07:23:49 -07:00
Ivan Gagis
b66ca4f326 use 2 images to build on appveyor 2017-06-15 11:49:10 +03:00
Ivan Gagis
4dc1054104 use powershell instead of cmd 2017-06-15 11:32:46 +03:00
Ivan Gagis
e944623780 Appveyor image set to VS2017 2017-06-15 11:17:34 +03:00
Ivan Gagis
042eae4c83 Appveyor image set to VS2017 2017-06-15 11:14:28 +03:00
Ivan Gagis
d8f9148d36 set v141 tools environment for building 2017-06-15 11:11:36 +03:00
Ivan Gagis
3a8073cca2 Appveyor image set to VS2017 2017-06-15 11:05:28 +03:00
Ivan Gagis
c7131b01f9 VS2017 project 2017-06-15 10:59:33 +03:00
Arseny Kapoulkine
0fbc043183 tests: Increase compact_pointer coverage
This adds tests that complete branch coverage in compact pointer
encoding/decoding code (previously first_attribute was always encoded
using compact encoding in the entire test suite).
2017-06-14 23:50:21 -07:00
Arseny Kapoulkine
52da6f71d0 Increase the minimum CMake version to 2.8.12
This is a followup to 198900eff4.

target_include_directories was introduced in 2.8.12, thus CMake 2.6 no
longer works.
2017-06-14 23:06:32 -07:00
Renaud Guillard
0d8022eced use snprintf if available, _snprintf or sprintf otherwise 2017-06-11 18:33:28 +02:00
Renaud Guillard
810f1f600d use _snprintf if MSVC 2017-06-05 13:31:58 +02:00
Renaud Guillard
b5e9d933ad use snprintf instead of sprintf 2017-06-04 21:10:19 +02:00
Arseny Kapoulkine
38edf255ae Work around -fsanitize=integer issues
Integer sanitizer is flagging unsigned integer overflow in several
functions in pugixml; unsigned integer overflow is well defined but it
may not necessarily be intended.

Apart from hash functions, both string_to_integer and integer_to_string
use unsigned overflow - string_to_integer uses it to perform
two-complement negation so that the bulk of the operation can run using
unsigned integers. This makes it possible to simplify overflow checking.
Similarly integer_to_string negates the number before generating a
decimal representation, but negating is impossible without unsigned
overflow or special-casing certain integer limits.

For now just silence the integer overflow using a special attribute;
also move unsigned overflow into string_to_integer from get_value_* so
that we have fewer functions marked with the attribute.

Fixes #133.
2017-04-03 23:35:24 -07:00
Arseny Kapoulkine
24d1a4562b Move libFuzzer build to Makefile
Now the only thing fuzz_setup.sh does is installing new clang; if system
clang supports -fsanitize-coverage then fuzz_setup.sh is not required.
2017-04-03 21:09:37 -07:00
Arseny Kapoulkine
0eb1ddb975 tests: Fix fuzz_setup.sh
The script only worked if clang folder was already created.
2017-04-03 20:36:33 -07:00
Arseny Kapoulkine
101f32884f Add missing PUGI__FN to string_to_integer 2017-03-21 22:06:19 -07:00
Arseny Kapoulkine
956be4ca4b Revert "Fix gcc-4.8 compilation warning when using -Wstrict-overflow"
This reverts commit 79109a8546.

This warning does not happen on gcc-4.8.4; the workaround introduces an
unsigned integer overflow which results in a runtime error when compiled
with integer sanitizer.
2017-03-21 21:57:16 -07:00
Arseny Kapoulkine
acfe47ba52 tests: Do not use unsigned underflow in test code
This triggers a runtime error under integer sanitizer
2017-03-21 21:47:22 -07:00
Arseny Kapoulkine
c29940ca72 tests: Fix invalid buffer size
This was triggering an buffer read overflow with asan.
2017-03-21 10:33:20 -07:00
Arseny Kapoulkine
db98a7e28b Fix path to fuzzing corpus 2017-03-21 10:28:20 -07:00
Arseny Kapoulkine
640c94f90d Merge pull request #134 from ogdf/explicit-fallthroughs
Silence g++ 7.0.1 -Wimplicit-fallthrough warnings
2017-03-06 07:43:40 -08:00
Stephan Beyer
87fc170cdf Silence g++ 7.0.1 -Wimplicit-fallthrough warnings
This is accomplished by putting a // fallthrough
comment at the right place.
This seems to be more portable than an attribute-based
solution like [[fallthrough]] or __attribute__((fallthrough)).
2017-03-05 22:12:10 +01:00
Arseny Kapoulkine
8ce4592e15 Simplify compact_hash_table implementation
Instead of a separate implementation for find/insert, use just one that
can do both. This reduces the code size and simplifies code coverage;
the resulting code is close to what we had in terms of performance and
since hash table is a fall back should not affect any real workloads.
2017-03-03 07:11:22 -08:00
Arseny Kapoulkine
03e4b8de92 Merge pull request #132 from zeux/fuzz
Improve fuzzing support
2017-02-11 13:51:39 -08:00
Arseny Kapoulkine
ec984370fb tests: Fix fuzz_setup.sh
Make the file executable, fix Windows newlines and fix clang setup.
2017-02-11 13:17:27 -08:00
Arseny Kapoulkine
ea544eb48b tests: Add fuzzing dictionaries
Hopefully this will allow for better fuzzing coverage
2017-02-11 13:17:02 -08:00
Arseny Kapoulkine
8c62fa9121 tests: Add XPath fuzzing
Only fuzz the parser for now.
2017-02-09 07:37:38 -08:00
Arseny Kapoulkine
8b15ae8015 tests: Add a script to set up fuzzing tools
This downloads a clang build that has support for instrumentation, and also
downloads and compiles libFuzzer.a.
2017-02-09 07:37:04 -08:00
Arseny Kapoulkine
00ef791078 fuzz: Use libFuzzer instead of afl-fuzz
This allows us to have faster fuzz cycles since the fuzzer is in-process.
2017-02-09 07:36:32 -08:00
Arseny Kapoulkine
e748f435e5 tests: Increase the number of translate calls
This should make the test fail on a 32-bit target.
2017-02-09 07:36:32 -08:00
Arseny Kapoulkine
4bab082a27 tests: Fix clang build 2017-02-09 07:36:32 -08:00
Arseny Kapoulkine
ba39838ab5 tests: Add more XPath out of memory tests 2017-02-09 07:36:31 -08:00
Arseny Kapoulkine
d4c456bdef Add invalid type assertion for offset_debug
This will make sure we don't forget to implement offset_debug for new
node types if they ever happen (really it's mostly for consistency).
2017-02-09 07:36:31 -08:00
Arseny Kapoulkine
02c599f52b tests: Increase the number of translate calls
This should make the test fail on a 32-bit target.
2017-02-08 01:18:11 -08:00
Arseny Kapoulkine
b98c914053 tests: Fix clang build 2017-02-08 00:33:51 -08:00
Arseny Kapoulkine
1688f44185 tests: Add more XPath out of memory tests 2017-02-08 00:09:32 -08:00
Arseny Kapoulkine
0991c1d283 Add invalid type assertion for offset_debug
This will make sure we don't forget to implement offset_debug for new
node types if they ever happen (really it's mostly for consistency).
2017-02-07 20:34:49 -08:00
Arseny Kapoulkine
2162a0d80c XPath: Simplify sorting implementation
Instead of a complicated partitioning scheme that tries to maintain the
equal area in the middle, use a scheme where we keep the equal area in
the left part of the array and then move it to the middle.

Since generally sorted arrays don't contain many duplicates this extra
copy is not too expensive, and it significantly simplifies the logic and
maintains good complexity for sorting arrays with many equal elements
nonetheless (unlike Hoare partitioning).

Instead of a median of 9 just use a median of 3 - it performs pretty
much identically on some internal performance tests, despite having a
bit more comparisons in some cases.

Finally, change the insertion sort threshold to 16 elements since that
appears to have slightly better performance.
2017-02-07 00:05:50 -08:00
Arseny Kapoulkine
774d5fe9df XPath: Optimize insertion_sort
The previous implementation opted for doing two comparisons per element
in the sorted case in order to remove one iterator bounds check per
moved element when we actually need to copy. In our case however the
comparator is pretty expensive (except for remove_duplicates which is
fast as it is) so an extra object comparison hurts much more than an
iterator comparison saves.

This makes sorting by document order up to 3% faster for random
sequences.
2017-02-06 19:28:33 -08:00
Arseny Kapoulkine
8cc3144e7b XPath: Remove redundant calls from xml_node::select_nodes et al
Instead of delegating to a method that just forwards the call to
xpath_query call the relevant method directly.
2017-02-05 21:52:30 -08:00
Arseny Kapoulkine
00e39c581a XPath: Remove evaluate_string_impl
It adds one stack frame to string query evaluation and does not really
simplify the code.
2017-02-05 21:50:13 -08:00
Arseny Kapoulkine
a9fe2bb62e Merge pull request #131 from zeux/xpath-noeh
XPath: Remove exceptional control flow
2017-02-05 21:34:54 -08:00
Arseny Kapoulkine
10676b6b85 tests: Add more XPath sorting tests
Cover empty node case - no XPath query can result in that but it's
possible to create a node set with empty nodes manually.
2017-02-05 21:12:55 -08:00
Arseny Kapoulkine
bcc7ed57a2 XPath: Simplify evaluation error flow
Instead of having two checks for out-of-memory when exceptions are
enabled, do just one and decide what to do based on whether we can
throw.
2017-02-03 20:33:40 -08:00
Arseny Kapoulkine
33159924b1 XPath: Clean up out-of-memory parse error handling
Instead of relying on a specific string in the parse result, use
allocator error state to report the error and then convert it to a
string if necessary.

We currently have to manually trigger the OOM error in two places
because we use global allocator in rare cases; we don't really need to
do this so this will be cleaned up later.
2017-02-02 18:40:20 -08:00
Arseny Kapoulkine
faadd460c4 tests: Add more out of memory tests for XPath evaluation 2017-02-02 08:57:02 -08:00
Arseny Kapoulkine
c28ff128d8 tests: Add more embed_pcdata tests 2017-02-02 08:40:34 -08:00
Arseny Kapoulkine
f9f1c86716 tests: Improve parsing coverage
Add tests for PI erroring exactly at the buffer boundary with
non-zero-terminated buffers (so we have to clear the last character
which changes the parsing flow slightly) and a test that makes sure
parse_embed_pcdata works properly with XML fragments where PCDATA can be
at the root level but can't be embedded into the document node.
2017-02-01 21:07:46 -08:00
Arseny Kapoulkine
0e3ccc7396 Remove redundant branch from xml_node::path()
The code works fine regardless of the *j->name check, and omitting this
makes the code more symmetric between the "count" and "write" stage;
additionally this improves coverage - due to how strcpy_insitu works
it's not really possible to get an empty non-NULL name in the node.
2017-02-01 21:05:37 -08:00
Arseny Kapoulkine
e56686f1e5 tests: Remove redundant coverage test
The only point was to try to test all paths where we can run out of
memory while decoding something. It seems like it may be impossible to
actually do this given that we can't run all paths as wchar_t size
detection is done at runtime...
2017-02-01 20:21:14 -08:00
Arseny Kapoulkine
1a3e92a7cc tests: Add more tests to increase coverage
This change adds more thorough tests for attribute conversion as well as
some assorted tests that fix gaps in coverage.
2017-01-31 20:40:50 -08:00
Arseny Kapoulkine
094a0c8ebe tests: Add compact hash table reserve test
This makes sure all .reserve calls failure paths are covered. These
tests don't explicitly test if reserve is present on all paths - this is
much harder to test since not all modifications require reserve to be
called, so we'll have to rely on a combination of automated testing and
sanity checking for this.

Also add more parsing out of memory coverage tests.
2017-01-31 19:19:04 -08:00
Arseny Kapoulkine
41fb880bf0 tests: Add coverage tests for encoding detection
Enumerate successfull cases and also cases where the detection stops
half-way and results in a different detected encoding.
2017-01-31 07:50:39 -08:00
Arseny Kapoulkine
ef64bef5c3 tests: More XPath coverage tests 2017-01-31 00:35:15 -08:00
Arseny Kapoulkine
6ffd2ffc41 tests: Add more DOM coverage tests
Add tests for various corner cases of DOM inspection and modification
routines.
2017-01-31 00:10:20 -08:00
Arseny Kapoulkine
9c7897b8d2 Remove null pointer test from first_element_by_path
All other functions treat null pointer inputs as invalid; now this
function does as well.
2017-01-30 23:55:31 -08:00
Arseny Kapoulkine
a1bc15c8d5 tests: Add more coverage tests
Expand out of memory coverage during XPath parsing and evaluation and
add some other small tests.
2017-01-30 23:52:32 -08:00
Arseny Kapoulkine
f500435cb4 XPath: Remove (re)allocate_throw and setjmp
Now error handling in XPath implementation relies on explicit error
propagation and is converted to an appropriate result at the end.
2017-01-30 22:31:57 -08:00
Arseny Kapoulkine
9e40c58532 XPath: Replace all (re)allocate_throw with (re)allocate_nothrow
This generates some out-of-memory code paths that are not covered by
existing tests, which will need to be resolved later.
2017-01-30 22:28:57 -08:00
Arseny Kapoulkine
60d5688a87 tests: Make predicate out-of-memory test less aggressive
Currently this test has very large runtime and relies on the fact that
the first memory allocation error causes the test to terminate. This
does not work with new behavior of running the query through and
reporting the error at the end, so make the runtime reasonable but still
generate enough memory to blow past the budget.
2017-01-30 22:27:48 -08:00
Arseny Kapoulkine
c370d1190d XPath: Fix reallocate_nothrow to preserve existing state
Instead of rolling back the allocation and trying to allocate again,
explicitly handle inplace reallocate if possible, and allocate a new
block otherwise.

This is going to be important once we use reallocate_nothrow from a
non-throwing context.
2017-01-30 22:10:13 -08:00
Arseny Kapoulkine
1a2e4b88ee XPath: Use nonthrowing allocations in duplicate_string
This requires explicit error handling for xpath_string::data calls.
2017-01-30 21:58:53 -08:00
Arseny Kapoulkine
ac150d504e XPath: Throw std::bad_alloc if we got an out-of-memory error
This allows us to gradually convert exception handling of out-of-memory
during evaluation to a non-throwing approach without changing the
observable behavior.
2017-01-30 21:58:53 -08:00
Arseny Kapoulkine
02cee98492 tests: Add more tests for branch coverage
gcov -b surfaced many lines with partial coverage, where branch is only
ever taken or not taken, or one of the expressions in a complex
conditional is always either true or false. This change adds a series of
tests (mostly focusing on XPath) to reduce the number of partially
covered lines.
2017-01-30 21:58:48 -08:00
Arseny Kapoulkine
cac1d8ad9f tests: Add an error propagation test for XPath
This test is supposed to test error coverage in different expressions
that are nested in other expressions to reduce the number of never-taken
branches in tests (and make sure we aren't missing any).
2017-01-30 11:51:07 -08:00
Arseny Kapoulkine
1b3e8614e7 XPath: Reword brace mismatch errors for clarity 2017-01-30 11:51:07 -08:00
Arseny Kapoulkine
1ed6d2102b XPath: Improve error message for expressions like .[1]
W3C specification does not allow predicates after abbreviated steps.
Currently this results in parsing terminating at the step, which leads
to confusing error messages like "Invalid query" or "Unmatched braces".
2017-01-30 11:51:07 -08:00
Arseny Kapoulkine
bc1e444694 XPath: Track allocation errors more explicitly
Any time an allocation fails xpath_allocator can set an externally
provided bool. The plan is to keep this bool up until evaluation ends,
so that we can use it to discard the potentially malformed result.
2017-01-30 11:51:07 -08:00
Arseny Kapoulkine
298996df11 Enable branch probabilities for gcov 2017-01-30 11:51:07 -08:00
Arseny Kapoulkine
635fe02801 XPath: Provide non-throwing and throwing allocations in xpath_allocator
For both allocate and reallocate, provide both _nothrow and _throw
functions; this change renames allocate() to allocate_throw() (same for
reallocate) to make it easier to change the code to remove throwing
variants.
2017-01-29 22:02:58 -08:00
Arseny Kapoulkine
8aa8e11ba6 tests: Add query out of memory test 2017-01-29 21:53:40 -08:00
Arseny Kapoulkine
6abf1d7c1a XPath: Minor error handling refactoring
Handle node type error before creating expression node
2017-01-29 21:53:23 -08:00
Arseny Kapoulkine
34b8c5908b Add NO_EXCEPTIONS build to Travis 2017-01-29 21:52:42 -08:00
Arseny Kapoulkine
4fa2241d7b XPath: Route out-of-memory errors through the exceptionless path
We currently need to convert error based on the text to a different type
of C++ exceptions when C++ exceptions are enabled.
2017-01-29 21:09:12 -08:00
Arseny Kapoulkine
bd8e2d782e XPath: Forward all node constructors through alloc_node
This allows us to handle OOM during node allocation without triggering
undefined behavior that occurs when placement new gets a NULL pointer.
2017-01-29 21:09:12 -08:00
Arseny Kapoulkine
293fccf3b0 XPath: Do not use exceptions to propagate parsing errors
Instead, return 0 and rely on parsing logic to propagate that all the
way down, and convert result to exception to maintain existing
interface.
2017-01-29 21:09:12 -08:00
Arseny Kapoulkine
7bb433b141 XPath: Assume that every function can fail and return 0
Propagate the failure to the caller manually. This is a first step to
parser structure that does not depend on exceptions or longjmp for error
handling (and thus matches the XML parser). To preserve semantics we'll
have to convert error code to exception later.
2017-01-29 21:09:12 -08:00
Arseny Kapoulkine
d72c0763f9 XPath: Minor parsing refactoring
Simplify function argument parsing by folding arg 0 parsing into the
main loop, reuse expression parsing logic for unary expression
2017-01-29 20:15:14 -08:00
Arseny Kapoulkine
60e580c2a8 XPath: Remove parse_function_helper
It was only used in three places and didn't really make the code more
readable.
2017-01-29 20:04:34 -08:00
Arseny Kapoulkine
f11c4d6847 XPath: alloc_string no longer returns NULL
NULL return value will be reserved for the OOM error indicator.
2017-01-29 20:00:44 -08:00
Arseny Kapoulkine
d3b9e4e1e8 Update copyright year to 2017 2017-01-26 20:12:06 -08:00
Daniel Knibbe
198900eff4 Added target_include_directories() to properly export include directories (#130)
Fixes #126
2017-01-17 09:30:01 -08:00
Arseny Kapoulkine
05edb250ee Work around cray++ compiler issue
It's still not clear as to what exactly makes it emit this error when compiling
string_to_integer:

CC-3059 crayc++: INTERNAL __C_FILE_SCOPE_DATA__, File = <pugixml>/src/pugixml.cpp, Line = 4524, Column = 4
  Expected no overflow in routine.

But a viable workaround for now is to exploit the knowledge that it uses
two-complement arithmetics and invert the sign manually.

Fixes #125.
2016-12-01 20:49:46 -08:00
Arseny Kapoulkine
e3524c90de scripts: Make archive build reproducible
We used to use the current timestamp when building the archive; switch to using
the timestamp of the tag with the version we're packaging.

This requires some monkey patching since tarfile module is always using current
timestamp when writing gzip header...

Also exclude archive.py from archive and simplify release file list in Makefile.
2016-11-28 23:24:27 -08:00
Arseny Kapoulkine
86ed1cf3b9 scripts: Move archive.py from tests 2016-11-27 17:55:41 -08:00
Arseny Kapoulkine
d2deb420bc Fix archive script to set timestamps properly for .tar.gz
By default they are set to Jan 1 1970 which breaks homebrew.

Fixes #124.
2016-11-27 12:09:12 -08:00
Arseny Kapoulkine
91bf70231a docs: Regenerate HTML documentation 2016-11-24 00:23:19 -08:00
Arseny Kapoulkine
5115db7409 tests: Fix unused variable warning in some compilers
The variable is being assigned to but never read when exceptions are
disabled.
2016-11-19 00:19:29 -08:00
Arseny Kapoulkine
8df9f97cda Silence 'cast increases required alignment of target type' warnings
These warnings are emitted on some GCC versions when targeting ARM; the
alignment is guaranteed to be correct due to how page offsets are set up
but the compiler doesn't know.
2016-11-18 09:49:31 -08:00
Arseny Kapoulkine
9366f25136 Rename set_value_convert to set_value_bool
It's too dangerous to overload here - easy to accidentally mix floating point
path with boolean one.
2016-11-17 21:37:27 -08:00
Arseny Kapoulkine
2af2524db5 Fix 'comparison of unsigned expression < 0 is always false' warnings
Unfortunately, some compilers don't suppress these kinds of warnings in
template instantiations; solve this by moving the responsibility for computing
negative bool to the caller.

Also since we're doing that we don't really need to convert to unsigned in the
implementation - might as well have the caller do it, which removes some type
dispatch logic and slightly reduces binary size.
2016-11-17 21:33:54 -08:00
Arseny Kapoulkine
6c2cd5210c scripts: Change VS2013 projects to use /Z7
Put debugging information into the object file so that it can be shipped
with NuGet binaries. Based on the linker settings for the executable
debug info will either be put into the final .PDB or stripped out.

Fixes #110.
2016-11-13 20:45:11 -08:00
Arseny Kapoulkine
80adb4ca5c Set 1.8 release date to (tentatively) Nov 24. 2016-11-13 17:04:33 -08:00
Arseny Kapoulkine
1e23402eb2 Change status_end_element_mismatch to point to closing tag name
Previously the error offset pointed to the first mismatching character, which
can be confusing especially if the start tag name is a prefix of the end tag
name. Instead, move the offset to the first character of the name - that way
it should be more obvious that the problem is that the entire name mismatches.

Fixes #112.
2016-11-13 16:59:14 -08:00
Arseny Kapoulkine
5ca7e7cffc Rewrite archive script into Python
Perl version needed Archive::Zip that for some reason is not installed on WSL by
default. Use this as an opportunity to remove the last Perl script.
2016-11-13 16:52:38 -08:00
Arseny Kapoulkine
c5223be434 tests: Fix MSVC warnings 2016-11-09 21:42:56 -08:00
Arseny Kapoulkine
2d47cde5d6 tests: Add a generalized write-roundtrip test
This test tests two important invariants:

- Every combination of write flags has to result in a valid document
- Parsing that document and saving the result has to result in identical output

We don't test all flags since parse_no_escapes can intentionally result in
malformed documents and other flags aren't relevant for node output.

Also note that we test both no-whitespace and whitespace version to make sure
we don't have unnecessary whitespace added during formatting.
2016-11-09 20:12:25 -08:00
Arseny Kapoulkine
c225b722cf docs: Add documentation for format_no_empty_element_tags
Also add it to the changelog for 1.8
2016-11-09 09:19:19 -08:00
Arseny Kapoulkine
1649b2e6b8 tests: Add a test for format_no_empty_element_tags 2016-11-09 09:12:36 -08:00
Arseny Kapoulkine
cd7e0b04f6 Add format_no_empty_element_tags flag
Setting this flag outputs start and end tag for every element, including empty
elements.

Fixes #118.
2016-11-09 09:11:30 -08:00
Arseny Kapoulkine
c75e3c45e5 Update version to 1.8 everywhere 2016-11-09 09:02:44 -08:00
Arseny Kapoulkine
57ef4ad459 docs: Add changelog draft for 1.8 2016-11-09 08:56:43 -08:00
Arseny Kapoulkine
17a215523c XPath: Fix source indentation
Split some lines into two and add braces in some places to make the code more
readable.
2016-11-08 07:14:59 -08:00
Arseny Kapoulkine
e4c43a0aa2 Move compact hash table pointer setup to xml_document
This keeps all code that creates document/allocator/page structures together.
2016-11-07 19:31:34 -08:00
Arseny Kapoulkine
9bc497267b Remove xml_allocator copying during parsing
The separate copy of allocator state in parser was meant to increase parsing
performance by reducing aliasing/indirection, but benchmarks against the
current source don't indicate that this is worthwhile.

Removing this simplifies the code slightly and makes it possible to move
compact hash table to the allocator.
2016-11-07 08:43:14 -08:00
Arseny Kapoulkine
2f98c62172 Rename xml_document::create/destroy for consistency 2016-11-07 08:22:54 -08:00
Arseny Kapoulkine
70f57fab6d tests: Don't use ranged for loop in move tests
Some compilers support move semantics but don't support ranged for.
2016-11-06 12:14:58 -08:00
Arseny Kapoulkine
0d015e9a2c Reduce MSVC version cutoff for move semantics support
MSVC 2010 supported move semantics (partially - but should be good enough for
our use case).
2016-11-06 11:51:16 -08:00
Arseny Kapoulkine
aa117cce42 Refactor move semantics support detection
Do it in one place and set PUGIXML_HAS_MOVE if it's available.
2016-11-06 11:49:10 -08:00
iFarbod
b3fc28d177 Add VS2013 check for C++11 availability (#121)
VS 2013 supports C++11, but __cplusplus macro isn't updated, and it is 199711 so the old check always fails, even though the compiler supports c++11.
2016-11-06 11:43:03 -08:00
Arseny Kapoulkine
a832e8a5ef Merge pull request #119 from pavelkryukov/master
Add C++11 'override' specifier
2016-10-17 20:36:49 -07:00
Pavel Kryukov
d0b0cc75ad Fix a comment before PUGIXML_OVERRIDE macro 2016-10-18 00:53:00 +03:00
Pavel Kryukov
c7c7349cb7 Add PUGIXML_OVERRIDE to headers of tests 2016-10-13 01:36:12 +03:00
Pavel Kryukov
3b58103157 Add 'override' keyword if C++11 is enabled 2016-10-05 20:11:07 +03:00
Arseny Kapoulkine
f53bddd7d5 Merge pull request #117 from digawp/quickstart-doc-fix
docs: Fix broken link at quickstart page
2016-09-21 23:20:16 -07:00
Diga Widyaprana
ddc8c1a795 Fix broken link 2016-09-22 14:03:13 +08:00
Arseny Kapoulkine
2933a03d09 CMake: Simplify install path logic
Select correct suffix to use for pkg-config
2016-09-20 22:16:47 -07:00
Arseny Kapoulkine
fd896d2476 CMake: Simplify pkg-config support
Merge USEOWNSUBDIR and PKGCONFIG build flags; move the pkg-config source file
to scripts/.
2016-09-20 22:11:42 -07:00
peterbud
0918dd2b99 Adding options PKGCONFIG build options 2016-09-13 21:03:11 +02:00
peterbud
6d69483bbc Adding PKG-CONFIG support
Also creating a separate install directory under INCLUDE and LIB directories
2016-09-12 21:44:20 +02:00
Arseny Kapoulkine
dfe9360cdf Merge pull request #109 from steji113/master
Remove static pivot from NuGet autopkg.
2016-08-08 08:24:20 -07:00
Arseny Kapoulkine
4451ab0b22 Add .codecov.yml to disable PR comments 2016-08-08 08:23:42 -07:00
Stephen Daudell
24ba24a465 Remove static pivot.
This pivot seemed to be causing issues because the NuGet package thought it was actually dynamic.
2016-08-08 10:04:54 -05:00
Arseny Kapoulkine
b9d8f22789 scripts: Fix indentation 2016-08-07 09:12:55 -07:00
Arseny Kapoulkine
55cea93e6c Merge pull request #108 from steji113/master
scripts: Add VS2013 static builds to nuget package
2016-08-07 09:06:41 -07:00
Stephen Daudell
ae984fbd54 Add custom toolset choices. 2016-08-04 14:56:52 -05:00
Stephen Daudell
97a6f65200 Potential fix for build issues. 2016-08-04 14:53:47 -05:00
Stephen Daudell
afe73da928 Expand build to include VS 2013. 2016-08-04 14:36:44 -05:00
Stephen Daudell
4d6556100f Update Nuget autopkg.
Include more configurations in the Nuget package.
2016-08-04 14:30:25 -05:00
Arseny Kapoulkine
bda8b72f81 Remove -b gcov argument
It interferes in a somewhat strange way with codecov reporting
2016-07-28 00:07:41 -05:00
Arseny Kapoulkine
666a01d335 Use references for output variables
While I grew to dislike references for this case, there are other functions in
the source that use references so switch to that for consistency.
2016-07-15 19:12:21 -05:00
Arseny Kapoulkine
5b102d108d tests: Fix clang warning 2016-07-15 18:53:59 -05:00
Arseny Kapoulkine
525b2fe5c3 tests: Add tests for latin1 detection 2016-07-14 23:04:17 -07:00
Arseny Kapoulkine
70d7c7904e Implement encoding detection by name.
This adds about 40 cycles for parsing <?xml version='1.0'?> declaration and
about 70 cycles for parsing <?xml version='1.0' encoding='utf-8'?>, as
measured on a Core i7, which should be negligible for all documents.

Fixes #16.
2016-07-14 22:44:23 -07:00
Arseny Kapoulkine
1d3befeaf8 Makefile: Add -Wcast-qual
It is probably redundant given that we have -Wold-style-cast, but it's better
to warn about casts like this in case we ever need to remove the latter flag.
2016-07-10 18:19:18 -07:00
Arseny Kapoulkine
4dbb564619 Only enable cxx_long_long_type if it is in the list of features
Fixes #99.
2016-06-18 01:51:28 -07:00
Arseny Kapoulkine
eec353c443 Switch to regular AppVeyor image 2016-06-10 21:18:13 -07:00
Arseny Kapoulkine
7699499f25 Add CMakeLists to 'make release' now that it's top-level 2016-06-10 21:12:00 -07:00
Arseny Kapoulkine
53bc83cae7 Merge pull request #90 from jippeholwerda/master
Put CMakeLists.txt in the project root.
2016-06-10 18:26:04 -07:00
Arseny Kapoulkine
937ac8116e Merge pull request #97 from HumMan/master
Add vs2013 projects
2016-05-15 20:19:41 -07:00
Alexsey Zazvonnykh
6439e0c1a1 Add vs2013 projects 2016-04-24 22:38:32 +03:00
Arseny Kapoulkine
2d5980b406 Adjust XML allocation pages to have the exact specified size
Previously the page size was defining the data size, and due to additional
headers (+ recently removed allocation padding) the actual allocation was a bit
bigger.

The problem is that some allocators round 2^N+k allocations to 2^N+M, which can
result in noticeable waste of space. Specifically, on 64-bit OSX allocating the
previous page size (32k+40) resulted in 32k+512 allocation, thereby wasting 472
bytes, or 1.4%.

Now we have the allocation size specified exactly and just recompute the available
data size, which can in small space savings depending on the allocator.
2016-04-14 08:43:06 -07:00
Arseny Kapoulkine
2e0ed8284b Remove extra space in an empty tag for format_raw
When using format_raw the space in the empty tag (<node />) is the only
character that does not have to be there; so format_raw almost results in
a minimal XML but not quite.

It's pretty unlikely that this is crucial for any users - the formatting
change should be benign, and it's better to improve format_raw than to add
yet another flag.

Fixes #87.
2016-04-14 00:30:24 -07:00
Arseny Kapoulkine
c6539ccef0 Refactor auto_deleter now that we only need to support one signature
Also rename auto_deleter_fclose to close_file.
2016-04-03 13:30:34 -07:00
Arseny Kapoulkine
54f87d3b59 Merge pull request #92 from QUSpilPrgm/master
Do not assume that fclose can be converted to int(*)(FILE*)
2016-04-03 13:27:12 -07:00
Arseny Kapoulkine
dba7932000 Fix AppVeyor build 2016-03-27 20:51:54 -07:00
QUSpilPrgm
0564d55e19 Do not assume that fclose can be converted to int(*)(FILE*) because some compilers use a special calling convention for stdlib functions like fclose 2016-03-24 17:33:10 +01:00
Jippe Holwerda
4469a32970 Change paths according to new CMakeLists.txt location. 2016-02-25 20:38:07 +01:00
Jippe Holwerda
806c75652a Put CMakeLists.txt in the project root.
Having CMakeLists.txt in the project root makes it so much easier to use pugixml
as an external dependency in another CMake project.
2016-02-25 19:30:03 +01:00
Arseny Kapoulkine
8b60bbdce4 scripts: Update license year 2016-02-13 13:07:53 -08:00
Arseny Kapoulkine
4bbf6255dd scripts: Rename CocoaPods script to match NuGet naming
Also remove top-level LICENSE file since .podspec already has it.
2016-02-13 13:07:19 -08:00
Arseny Kapoulkine
44c251fbc3 Merge pull request #85 from igagis/master
scripts: Add CocoaPods package
2016-02-13 13:05:41 -08:00
Ivan Gagis
b709f15d18 embed license to podspec, as LICENSE file is not in 1.7 tag, cocoapods errors otherwise. Get sources from zeux github 2016-02-03 19:29:40 +02:00
Ivan Gagis
4215a0a159 LICENSE, podspec 2016-02-03 19:09:24 +02:00
Arseny Kapoulkine
607e46f209 Refactor conversion from integer to string
Unify the implementations by automatically deducing the unsigned type from its
signed counterpart. That allows us to use a templated function instead of
duplicating code.
2016-02-02 10:44:35 -08:00
Arseny Kapoulkine
ac4a84df4d docs: Add documentation for long setters 2016-02-02 08:52:47 -08:00
Arseny Kapoulkine
d2e72ee05a tests: Add tests for long setters 2016-02-02 08:49:32 -08:00
Arseny Kapoulkine
f441c63ea4 Implement set/set_value/operator= for long types
This makes the coverage for basic numeric types complete (sans long double).

Fixes #78.
2016-02-02 08:39:45 -08:00
Arseny Kapoulkine
c712dd84ba Specify std=c++11 explicitly in Travis configurations
That way the defaults in the Makefile only matter for local runs.
2016-01-26 21:43:48 -08:00
Arseny Kapoulkine
c3d27daf8e Merge pull request #83 from ogdf/use-real-standards-only
Add cxxstd Makefile argument for testing C++ standards
2016-01-26 20:28:10 -08:00
Stephan Beyer
e017a22fe0 Let Travis CI perform C++98-based tests 2016-01-26 22:14:58 +01:00
Stephan Beyer
6bbbdb7d7e Make cxxstd an argument to Makefile
This determines the used C++ standard.
If you do not want to use a specific C++ standard, use cxxstd=any.
The default is set to c++11.

The "define" PUGIXML_NO_CXX11 is removed from the Makefile
since it is not used in the code anyways.
2016-01-26 22:14:58 +01:00
Stephan Beyer
fb647f69a2 Let Travis CI use Ubuntu trusty
This allows to perform C++11-based tests on the Linux.
2016-01-26 21:53:16 +01:00
Stephan Beyer
fc9073289f test_parse.cpp: add newline to last line
This is necessary in order to comply with the C++03 standard.
2016-01-24 19:47:06 +01:00
Arseny Kapoulkine
e133764f33 Merge pull request #81 from ogdf/whitespace-issues
Fix whitespace issues
2016-01-24 08:56:06 -08:00
Stephan Beyer
f7aa65db8a Fix whitespace issues
Git warns when it finds "whitespace errors". This commit gets
rid of these whitespace errors for code and adoc files.
2016-01-24 14:05:44 +01:00
Arseny Kapoulkine
7f91301946 Change header format in non-compact mode to store page offset
This utilizes the fact that pages are of limited size so we can store offset
from the object to the page in a few bits - we currently use 24 although that's
excessive given that pages are limited to ~512k.

This has several benefits:

- Pages do not have to be 64b aligned any more - this simplifies allocation flow
and frees up 40-50 bytes from xml_document::_memory.

- Header now has 8 bits available for metadata for both compact and default mode
which makes it possible to store type as-is (allowing easy type extension and
removing one add/sub operation from type checks).

- One extra bit is easily available for future metadata extension (in addition
to the bit for type encoding that could be reclaimed if necessary).

- Allocators that return 4b-aligned memory on 64-bit platforms work fine if
misaligned reads are supported.

The downside is that there is one or two extra instructions on the allocation
path. This does not seem to hurt parsing performance.
2016-01-20 21:51:02 -08:00
Arseny Kapoulkine
7aef75f43d docs: Adjust as_int documentation to match implementation
Also remove the description of behavior for trailing non-numeric characters.
It's likely this will become a parse error in the future so better leave it
as unspecified for now.

Fixes #80.
2016-01-19 21:17:08 -08:00
Arseny Kapoulkine
c388dbeba4 Merge pull request #79 from zeux/embed-pcdata
Add parse_embed_pcdata flag

This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of the document; this flag is only recommended for parsing documents with a lot of PCDATA nodes in a very memory-constrained environment.

Most high-level APIs continue to work; code that inspects DOM using first_child()/value() will have to be adapted.
2016-01-14 07:52:40 -08:00
Arseny Kapoulkine
4f3be76167 Preserve order semantics for child_value/text when using parse_embed_pcdata
The performance cost is probably negligible and this means we treat embedded
value as the first child consistently.
2016-01-12 20:41:37 -08:00
Arseny Kapoulkine
85238132d3 docs: Add parse_embed_pcdata documentation 2016-01-12 20:38:45 -08:00
Arseny Kapoulkine
71d3a797f4 Adjust parse_embed_pcdata documentation
Since round-tripping should not be a problem any more don't mention it.
2016-01-12 20:18:12 -08:00
Arseny Kapoulkine
fc6c8633dd tests: Add test for parse_embed_pcdata 2016-01-12 20:16:29 -08:00
Arseny Kapoulkine
bcddf36559 Only save first PCDATA contents in the element
This change fixes an important ordering issue - if element node has a PCDATA
child *after* other elements, it's impossible to tell which order the children
were in.

Since the goal of PCDATA embedding is to save memory when it's the only child,
only apply the optimization to the first child. This seems to fix all
roundtripping issues so the only caveat is that the DOM structure is different.
2016-01-12 20:01:44 -08:00
Arseny Kapoulkine
df2a0ad28b Implement output support for embedded PCDATA values
This is a bit awkward since preserving correct indentation structure requires
a bit of extra work, and the closing tag has to be written by _start function
to correctly process the rest of the tree.
2016-01-09 17:46:42 -08:00
Arseny Kapoulkine
85d8b225f2 Support XPath string value for parse_embed_pcdata 2016-01-08 08:41:38 -08:00
Arseny Kapoulkine
8b01f8923c Support xml_node::child_value/text for parse_embed_pcdata 2016-01-08 08:40:56 -08:00
Arseny Kapoulkine
2874f6f21d Add initial support for parse_embed_pcdata
When this flag is true, PCDATA value is saved to the parent element instead of
allocating a new node.

This prevents some documents from round-tripping since it loses information,
but can provide a significant memory reduction and parsing speedup for some
documents.
2016-01-08 08:37:26 -08:00
Arseny Kapoulkine
ad3b492c1a docs: Regenerate HTML documentation 2015-12-31 17:22:41 +03:00
Arseny Kapoulkine
5f58e9bd0c Update all license/copyright texts to 2016 2015-12-31 17:22:21 +03:00
Arseny Kapoulkine
af7177e77d docs: Use ISO-8601 for changelog dates 2015-12-31 17:11:54 +03:00
Arseny Kapoulkine
03b1b6a5c3 scripts: Fix default value for STATIC_CRT option
Also refactor to use the same case and run after common options.
2015-12-30 23:58:03 +03:00
Arseny Kapoulkine
6a22a28730 Merge pull request #70 from nirbar/master
scripts: Allow linking static CRT libraries on Windows

Use the solution from CMake FAQ to specify correct command-line arguments.
2015-12-30 23:54:58 +03:00
Arseny Kapoulkine
1bcf12402e Work around Clang Wstring-conversion warnings
(!"string") triggers the warning however (false && "string") does not.

Fixes #75.
2015-12-29 21:43:24 +03:00
nir.bar
3dadebf10e Merge branch 'master' of github.com:nirbar/pugixml 2015-12-03 13:19:52 +02:00
nir.bar
0d111976e1 Add CMake option on MSVC- STATIC_CRT 2015-12-03 12:33:44 +02:00
Arseny Kapoulkine
2cf599b310 Work around MinGW versions with non-C99 compliant headers
Apparently some MinGW distributions have a compiler that's recent enough to
support C++11 but limits.h header that incorrectly omits LLONG limits in
strict ANSI mode, since it guards the definitions with:

	#if !defined(__STRICT_ANSI__) && defined(__GNUC__)

We can just define these symbols ourselves in this specific case.

Fixes #66.
2015-11-13 09:09:43 -08:00
Arseny Kapoulkine
94c08f27c6 tests: Fix Borland C++ 5.4 compilation
The tests now compile fine but crash on the first floating-point exception
despite our attempts to disable them in main()...
2015-10-25 13:44:26 -07:00
Arseny Kapoulkine
fe58041a61 Fix Borland C++ 5.4 compilation
It does not have stdint.h and has some C++ parsing issues.
2015-10-25 12:57:43 -07:00
Arseny Kapoulkine
39149fd5bd Reduce Travis build matrix 2015-10-24 14:15:47 -07:00
Arseny Kapoulkine
0fe295aa9c Build NuGet package on AppVeyor 2015-10-23 11:11:49 -07:00
Arseny Kapoulkine
a3a9d53860 docs: Fix CDATA example
Fixes #61.
2015-10-19 20:55:39 -07:00
Arseny Kapoulkine
7d2842e670 docs: Add iOS to the list of supported platforms 2015-10-19 00:11:10 -07:00
Arseny Kapoulkine
5b2f014fc7 docs: Update packaging info 2015-10-18 21:01:14 -07:00
100 changed files with 10473 additions and 4191 deletions

7
.codecov.yml Normal file
View file

@ -0,0 +1,7 @@
comment: false
coverage:
status:
project:
default:
informational: true
patch: off

1
.gitattributes vendored Normal file
View file

@ -0,0 +1 @@
tests/data/* -text

8
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,8 @@
---
name: Bug report
about: Create a report if you believe you've found a bug in this project; please use GitHub Discussions instead if you think the bug may be in your code.
title: ''
labels: bug
assignees: ''
---

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View file

@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Help and support
url: https://github.com/zeux/pugixml/discussions
about: Please use GitHub Discussions if you have questions or need help.

View file

@ -0,0 +1,8 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---

52
.github/workflows/build.yml vendored Normal file
View file

@ -0,0 +1,52 @@
name: build
on:
push:
branches:
- 'master'
pull_request:
jobs:
unix:
strategy:
matrix:
os: [ubuntu, macos]
compiler: [g++, clang++]
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS]
exclude:
- os: macos
compiler: g++
name: ${{matrix.os}} (${{matrix.compiler}}, ${{matrix.defines}})
runs-on: ${{matrix.os}}-latest
steps:
- uses: actions/checkout@v1
- name: make test
run: |
export CXX=${{matrix.compiler}}
make test cxxstd=c++11 defines=${{matrix.defines}} config=release -j2
make test cxxstd=c++98 defines=${{matrix.defines}} config=debug -j2
make test defines=${{matrix.defines}} config=sanitize -j2
- name: make coverage
if: ${{!(matrix.os == 'ubuntu' && matrix.compiler == 'clang++')}} # linux/clang produces coverage info gcov can't parse
run: |
export CXX=${{matrix.compiler}}
make test defines=${{matrix.defines}} config=coverage -j2
bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}}
windows:
runs-on: windows-latest
strategy:
matrix:
arch: [Win32, x64]
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS]
steps:
- uses: actions/checkout@v1
- name: cmake configure
run: cmake . -DPUGIXML_BUILD_TESTS=ON -D${{matrix.defines}}=ON -A ${{matrix.arch}}
- name: cmake test
shell: bash # necessary for fail-fast
run: |
cmake --build . -- -property:Configuration=Debug -verbosity:minimal
Debug/pugixml-check.exe
cmake --build . -- -property:Configuration=Release -verbosity:minimal
Release/pugixml-check.exe

3
.gitignore vendored
View file

@ -1 +1,2 @@
build/
/build/
/.vscode/

View file

@ -1,14 +0,0 @@
sudo: false
language: cpp
os:
- linux
- osx
env:
- CONFIG=coverage DEFINES=standard
- CONFIG=coverage DEFINES=PUGIXML_WCHAR_MODE
- CONFIG=coverage DEFINES=PUGIXML_COMPACT
- CONFIG=release DEFINES=standard
- CONFIG=release DEFINES=PUGIXML_WCHAR_MODE
- CONFIG=release DEFINES=PUGIXML_COMPACT
script: make test defines=$DEFINES config=$CONFIG -j2
after_success: bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov

263
CMakeLists.txt Normal file
View file

@ -0,0 +1,263 @@
cmake_minimum_required(VERSION 3.4)
project(pugixml VERSION 1.13 LANGUAGES CXX)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)
include(GNUInstallDirs)
include(CTest)
cmake_dependent_option(PUGIXML_USE_VERSIONED_LIBDIR
"Use a private subdirectory to install the headers and libraries" OFF
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(PUGIXML_USE_POSTFIX
"Use separate postfix for each configuration to make sure you can install multiple build outputs" OFF
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
cmake_dependent_option(PUGIXML_STATIC_CRT
"Use static MSVC RT libraries" OFF
"MSVC" OFF)
cmake_dependent_option(PUGIXML_BUILD_TESTS
"Build pugixml tests" OFF
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
# Custom build defines
set(PUGIXML_BUILD_DEFINES CACHE STRING "Build defines for custom options")
separate_arguments(PUGIXML_BUILD_DEFINES)
# Technically not needed for this file. This is builtin CMAKE global variable.
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
# Expose option to build PUGIXML as static as well when the global BUILD_SHARED_LIBS variable is set
cmake_dependent_option(PUGIXML_BUILD_SHARED_AND_STATIC_LIBS
"Build both shared and static libraries" OFF
"BUILD_SHARED_LIBS" OFF)
# Expose options from the pugiconfig.hpp
option(PUGIXML_WCHAR_MODE "Enable wchar_t mode" OFF)
option(PUGIXML_COMPACT "Enable compact mode" OFF)
# Advanced options from pugiconfig.hpp
option(PUGIXML_NO_XPATH "Disable XPath" OFF)
option(PUGIXML_NO_STL "Disable STL" OFF)
option(PUGIXML_NO_EXCEPTIONS "Disable Exceptions" OFF)
mark_as_advanced(PUGIXML_NO_XPATH PUGIXML_NO_STL PUGIXML_NO_EXCEPTIONS)
# Policy configuration
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW) # Enables use of MSVC_RUNTIME_LIBRARY
endif()
set(PUGIXML_PUBLIC_DEFINITIONS
$<$<BOOL:${PUGIXML_WCHAR_MODE}>:PUGIXML_WCHAR_MODE>
$<$<BOOL:${PUGIXML_COMPACT}>:PUGIXML_COMPACT>
$<$<BOOL:${PUGIXML_NO_XPATH}>:PUGIXML_NO_XPATH>
$<$<BOOL:${PUGIXML_NO_STL}>:PUGIXML_NO_STL>
$<$<BOOL:${PUGIXML_NO_EXCEPTIONS}>:PUGIXML_NO_EXCEPTIONS>)
# This is used to backport a CMake 3.15 feature, but is also forwards compatible
if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
set(CMAKE_MSVC_RUNTIME_LIBRARY
MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<NOT:$<BOOL:${PUGIXML_STATIC_CRT}>>:DLL>)
endif()
if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
if (NOT DEFINED CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 11)
endif()
if (PUGIXML_USE_POSTFIX)
set(CMAKE_RELWITHDEBINFO_POSTFIX _r)
set(CMAKE_MINSIZEREL_POSTFIX _m)
set(CMAKE_DEBUG_POSTFIX _d)
endif()
if (CMAKE_VERSION VERSION_LESS 3.15)
set(msvc-rt $<TARGET_PROPERTY:MSVC_RUNTIME_LIBRARY>)
set(msvc-rt-mtd-shared $<STREQUAL:${msvc-rt},MultiThreadedDebugDLL>)
set(msvc-rt-mtd-static $<STREQUAL:${msvc-rt},MultiThreadedDebug>)
set(msvc-rt-mt-shared $<STREQUAL:${msvc-rt},MultiThreadedDLL>)
set(msvc-rt-mt-static $<STREQUAL:${msvc-rt},MultiThreaded>)
unset(msvc-rt)
set(msvc-rt-mtd-shared $<${msvc-rt-mtd-shared}:-MDd>)
set(msvc-rt-mtd-static $<${msvc-rt-mtd-static}:-MTd>)
set(msvc-rt-mt-shared $<${msvc-rt-mt-shared}:-MD>)
set(msvc-rt-mt-static $<${msvc-rt-mt-static}:-MT>)
endif()
set(versioned-dir $<$<BOOL:${PUGIXML_USE_VERSIONED_LIBDIR}>:/pugixml-${PROJECT_VERSION}>)
set(libs)
if (BUILD_SHARED_LIBS)
add_library(pugixml-shared SHARED
${PROJECT_SOURCE_DIR}/scripts/pugixml_dll.rc
${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
add_library(pugixml::shared ALIAS pugixml-shared)
list(APPEND libs pugixml-shared)
string(CONCAT pugixml.msvc $<OR:
$<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},MSVC>,
$<CXX_COMPILER_ID:MSVC>
>)
set_property(TARGET pugixml-shared PROPERTY EXPORT_NAME shared)
target_include_directories(pugixml-shared
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
target_compile_definitions(pugixml-shared
PUBLIC
${PUGIXML_BUILD_DEFINES}
${PUGIXML_PUBLIC_DEFINITIONS}
PRIVATE
PUGIXML_API=$<IF:${pugixml.msvc},__declspec\(dllexport\),__attribute__\(\(visibility\("default"\)\)\)>
)
target_compile_options(pugixml-shared
PRIVATE
${msvc-rt-mtd-shared}
${msvc-rt-mtd-static}
${msvc-rt-mt-shared}
${msvc-rt-mt-static})
endif()
if (NOT BUILD_SHARED_LIBS OR PUGIXML_BUILD_SHARED_AND_STATIC_LIBS)
add_library(pugixml-static STATIC
${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
add_library(pugixml::static ALIAS pugixml-static)
list(APPEND libs pugixml-static)
set_property(TARGET pugixml-static PROPERTY EXPORT_NAME static)
target_include_directories(pugixml-static
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>)
target_compile_definitions(pugixml-static
PUBLIC
${PUGIXML_BUILD_DEFINES}
${PUGIXML_PUBLIC_DEFINITIONS})
target_compile_options(pugixml-static
PRIVATE
${msvc-rt-mtd-shared}
${msvc-rt-mtd-static}
${msvc-rt-mt-shared}
${msvc-rt-mt-static})
endif()
if (BUILD_SHARED_LIBS)
set(pugixml-alias pugixml-shared)
else()
set(pugixml-alias pugixml-static)
endif()
add_library(pugixml INTERFACE)
target_link_libraries(pugixml INTERFACE ${pugixml-alias})
add_library(pugixml::pugixml ALIAS pugixml)
set_target_properties(${libs}
PROPERTIES
MSVC_RUNTIME_LIBRARY ${CMAKE_MSVC_RUNTIME_LIBRARY}
EXCLUDE_FROM_ALL ON
POSITION_INDEPENDENT_CODE ON
SOVERSION ${PROJECT_VERSION_MAJOR}
VERSION ${PROJECT_VERSION}
OUTPUT_NAME pugixml)
set_target_properties(${libs}
PROPERTIES
EXCLUDE_FROM_ALL OFF)
set(install-targets pugixml ${libs})
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/scripts/pugixml-config.cmake.in"
"${PROJECT_BINARY_DIR}/pugixml-config.cmake"
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}
NO_CHECK_REQUIRED_COMPONENTS_MACRO
NO_SET_AND_CHECK_MACRO)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
COMPATIBILITY SameMajorVersion)
if (PUGIXML_USE_POSTFIX)
if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
set(LIB_POSTFIX ${CMAKE_RELWITHDEBINFO_POSTFIX})
elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
set(LIB_POSTFIX ${CMAKE_MINSIZEREL_POSTFIX})
elseif(CMAKE_BUILD_TYPE MATCHES Debug)
set(LIB_POSTFIX ${CMAKE_DEBUG_POSTFIX})
endif()
endif()
configure_file(scripts/pugixml.pc.in pugixml.pc @ONLY)
if (NOT DEFINED PUGIXML_RUNTIME_COMPONENT)
set(PUGIXML_RUNTIME_COMPONENT Runtime)
endif()
if (NOT DEFINED PUGIXML_LIBRARY_COMPONENT)
set(PUGIXML_LIBRARY_COMPONENT Library)
endif()
if (NOT DEFINED PUGIXML_DEVELOPMENT_COMPONENT)
set(PUGIXML_DEVELOPMENT_COMPONENT Development)
endif()
set(namelink-component)
if (NOT CMAKE_VERSION VERSION_LESS 3.12)
set(namelink-component NAMELINK_COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
endif()
install(TARGETS ${install-targets}
EXPORT pugixml-targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${PUGIXML_RUNTIME_COMPONENT}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_LIBRARY_COMPONENT} ${namelink-component}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir})
install(EXPORT pugixml-targets
NAMESPACE pugixml::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
export(EXPORT pugixml-targets
NAMESPACE pugixml::)
install(FILES
"${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
"${PROJECT_BINARY_DIR}/pugixml-config.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
install(
FILES
"${PROJECT_SOURCE_DIR}/src/pugiconfig.hpp"
"${PROJECT_SOURCE_DIR}/src/pugixml.hpp"
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
if (PUGIXML_BUILD_TESTS)
set(fuzz-pattern "tests/fuzz_*.cpp")
set(test-pattern "tests/*.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.11)
list(INSERT fuzz-pattern 0 CONFIGURE_DEPENDS)
list(INSERT test-pattern 0 CONFIGURE_DEPENDS)
endif()
file(GLOB test-sources ${test-pattern})
file(GLOB fuzz-sources ${fuzz-pattern})
list(REMOVE_ITEM test-sources ${fuzz-sources})
add_custom_target(check
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
add_executable(pugixml-check ${test-sources})
add_test(NAME pugixml::test
COMMAND pugixml-check
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
add_dependencies(check pugixml-check)
target_link_libraries(pugixml-check
PRIVATE
pugixml::pugixml)
endif()

24
LICENSE.md Normal file
View file

@ -0,0 +1,24 @@
MIT License
Copyright (c) 2006-2022 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

View file

@ -3,16 +3,18 @@ MAKEFLAGS+=-r
config=debug
defines=standard
cxxstd=c++11
# set cxxstd=any to disable use of -std=...
BUILD=build/make-$(CXX)-$(config)-$(defines)
BUILD=build/make-$(CXX)-$(config)-$(defines)-$(cxxstd)
SOURCES=src/pugixml.cpp $(filter-out tests/fuzz_%,$(wildcard tests/*.cpp))
EXECUTABLE=$(BUILD)/test
VERSION=$(shell sed -n 's/.*version \(.*\).*/\1/p' src/pugiconfig.hpp)
RELEASE=$(shell git ls-files src docs/*.html docs/*.css docs/samples docs/images scripts contrib readme.txt)
RELEASE=$(filter-out scripts/archive.py docs/%.adoc,$(shell git ls-files docs scripts src CMakeLists.txt LICENSE.md readme.txt))
CXXFLAGS=-g -Wall -Wextra -Werror -pedantic -Wundef -Wshadow -Wold-style-cast -Wcast-align
CXXFLAGS=-g -Wall -Wextra -Werror -pedantic -Wundef -Wshadow -Wcast-align -Wcast-qual -Wold-style-cast -Wdouble-promotion
LDFLAGS=
ifeq ($(config),release)
@ -25,13 +27,8 @@ ifeq ($(config),coverage)
endif
ifeq ($(config),sanitize)
CXXFLAGS+=-fsanitize=address
LDFLAGS+=-fsanitize=address
ifneq ($(shell uname),Darwin)
CXXFLAGS+=-fsanitize=undefined
LDFLAGS+=-fsanitize=undefined
endif
CXXFLAGS+=-fsanitize=address,undefined -fno-sanitize=float-divide-by-zero,float-cast-overflow -fno-sanitize-recover=all
LDFLAGS+=-fsanitize=address,undefined
endif
ifeq ($(config),analyze)
@ -47,9 +44,8 @@ ifneq ($(findstring PUGIXML_NO_EXCEPTIONS,$(defines)),)
CXXFLAGS+=-fno-exceptions
endif
ifeq ($(findstring PUGIXML_NO_CXX11,$(defines)),)
# Can't use std=c++11 since Travis-CI has gcc 4.6.3
CXXFLAGS+=-std=c++0x
ifneq ($(cxxstd),any)
CXXFLAGS+=-std=$(cxxstd)
endif
OBJECTS=$(SOURCES:%=$(BUILD)/%.o)
@ -62,15 +58,15 @@ test: $(EXECUTABLE)
./$(EXECUTABLE)
@gcov -b -o $(BUILD)/src/ pugixml.cpp.gcda | sed -e '/./{H;$!d;}' -e 'x;/pugixml.cpp/!d;'
@find . -name '*.gcov' -and -not -name 'pugixml.cpp.gcov' -exec rm {} +
@sed -i -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ 1\1\2/" pugixml.cpp.gcov
else
test: $(EXECUTABLE)
./$(EXECUTABLE)
endif
fuzz:
@mkdir -p $(BUILD)
$(AFL)/afl-clang++ tests/fuzz_parse.cpp tests/allocator.cpp src/pugixml.cpp $(CXXFLAGS) -o $(BUILD)/fuzz_parse
$(AFL)/afl-fuzz -i tests/data_fuzz_parse -o $(BUILD)/fuzz_parse_out -x $(AFL)/testcases/_extras/xml/ -- $(BUILD)/fuzz_parse @@
fuzz_%: $(BUILD)/fuzz_%
@mkdir -p build/$@
$< build/$@ tests/data_fuzz_$* -max_len=1024 -dict=tests/fuzz_$*.dict
clean:
rm -rf $(BUILD)
@ -81,11 +77,15 @@ docs: docs/quickstart.html docs/manual.html
build/pugixml-%: .FORCE | $(RELEASE)
@mkdir -p $(BUILD)
perl tests/archive.pl $@ $|
TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python3 scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
$(BUILD)/fuzz_%: tests/fuzz_%.cpp src/pugixml.cpp
@mkdir -p $(BUILD)
$(CXX) $(CXXFLAGS) -fsanitize=address,fuzzer $^ -o $@
$(BUILD)/%.o: %
@mkdir -p $(dir $@)
$(CXX) $< $(CXXFLAGS) -c -MMD -MP -o $@

View file

@ -1,4 +1,4 @@
pugixml [![Build Status](https://travis-ci.org/zeux/pugixml.svg?branch=master)](https://travis-ci.org/zeux/pugixml) [![Build status](https://ci.appveyor.com/api/projects/status/9hdks1doqvq8pwe7/branch/master?svg=true)](https://ci.appveyor.com/project/zeux/pugixml) [![codecov.io](http://codecov.io/github/zeux/pugixml/coverage.svg?branch=master)](http://codecov.io/github/zeux/pugixml?branch=master)
pugixml [![Actions Status](https://github.com/zeux/pugixml/workflows/build/badge.svg)](https://github.com/zeux/pugixml/actions) [![Build status](https://ci.appveyor.com/api/projects/status/9hdks1doqvq8pwe7/branch/master?svg=true)](https://ci.appveyor.com/project/zeux/pugixml) [![codecov.io](https://codecov.io/github/zeux/pugixml/coverage.svg?branch=master)](https://codecov.io/github/zeux/pugixml?branch=master) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg)
=======
pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification
@ -12,33 +12,61 @@ pugixml is used by a lot of projects, both open-source and proprietary, for perf
Documentation for the current release of pugixml is available on-line as two separate documents:
* [Quick-start guide](http://pugixml.org/docs/quickstart.html), that aims to provide enough information to start using the library;
* [Complete reference manual](http://pugixml.org/docs/manual.html), that describes all features of the library in detail.
* [Quick-start guide](https://pugixml.org/docs/quickstart.html), that aims to provide enough information to start using the library;
* [Complete reference manual](https://pugixml.org/docs/manual.html), that describes all features of the library in detail.
Youre advised to start with the quick-start guide; however, many important library features are either not described in it at all or only mentioned briefly; if you require more information you should read the complete manual.
## Example
Here's an example of how code using pugixml looks; it opens an XML file, goes over all Tool nodes and prints tools that have a Timeout attribute greater than 0:
```c++
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("xgconsole.xml");
if (!result)
return -1;
for (pugi::xml_node tool: doc.child("Profile").child("Tools").children("Tool"))
{
int timeout = tool.attribute("Timeout").as_int();
if (timeout > 0)
std::cout << "Tool " << tool.attribute("Filename").value() << " has timeout " << timeout << "\n";
}
}
```
And the same example using XPath:
```c++
#include "pugixml.hpp"
#include <iostream>
int main()
{
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file("xgconsole.xml");
if (!result)
return -1;
pugi::xpath_node_set tools_with_timeout = doc.select_nodes("/Profile/Tools/Tool[@Timeout > 0]");
for (pugi::xpath_node node: tools_with_timeout)
{
pugi::xml_node tool = node.node();
std::cout << "Tool " << tool.attribute("Filename").value() <<
" has timeout " << tool.attribute("Timeout").as_int() << "\n";
}
}
```
## License
This library is available to anybody free of charge, under the terms of MIT License:
Copyright (c) 2006-2015 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
This library is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).

9
SECURITY.md Normal file
View file

@ -0,0 +1,9 @@
# Security Policy
## Supported Versions
Please verify that the vulnerabilities reported can be reproduced on the [latest released version](https://github.com/zeux/pugixml/releases).
## Reporting a Vulnerability
Vulnerabilities can be reported via e-mail to the [project maintainer](https://github.com/zeux).

View file

@ -1,5 +1,25 @@
os: Visual Studio 2015 RC
image:
- Visual Studio 2022
- Visual Studio 2019
- Visual Studio 2017
- Visual Studio 2015
version: "{branch}-{build}"
build_script:
- ps: .\tests\autotest-appveyor.ps1
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2013") { .\scripts\nuget_build.ps1 2013}
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\scripts\nuget_build.ps1 2015}
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\scripts\nuget_build.ps1 2017}
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\scripts\nuget_build.ps1 2019}
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\scripts\nuget_build.ps1 2022}
test_script:
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 9 10 11 12 14 }
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\tests\autotest-appveyor.ps1 15 }
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\tests\autotest-appveyor.ps1 19 }
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\tests\autotest-appveyor.ps1 22 }
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make config=coverage test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make config=coverage defines=PUGIXML_WCHAR_MODE test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
artifacts:
- path: .\scripts\*.nupkg

View file

@ -1,63 +0,0 @@
/*
* Boost.Foreach support for pugixml classes.
* This file is provided to the public domain.
* Written by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
*/
#ifndef HEADER_PUGIXML_FOREACH_HPP
#define HEADER_PUGIXML_FOREACH_HPP
#include <boost/range/iterator.hpp>
#include "pugixml.hpp"
/*
* These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child iteration only).
* Example usage:
* BOOST_FOREACH(xml_node n, doc) {}
*/
namespace boost
{
template<> struct range_mutable_iterator<pugi::xml_node>
{
typedef pugi::xml_node::iterator type;
};
template<> struct range_const_iterator<pugi::xml_node>
{
typedef pugi::xml_node::iterator type;
};
template<> struct range_mutable_iterator<pugi::xml_document>
{
typedef pugi::xml_document::iterator type;
};
template<> struct range_const_iterator<pugi::xml_document>
{
typedef pugi::xml_document::iterator type;
};
}
/*
* These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child/attribute iteration).
* Example usage:
* BOOST_FOREACH(xml_node n, children(doc)) {}
* BOOST_FOREACH(xml_node n, attributes(doc)) {}
*/
namespace pugi
{
inline xml_object_range<xml_node_iterator> children(const pugi::xml_node& node)
{
return node.children();
}
inline xml_object_range<xml_attribute_iterator> attributes(const pugi::xml_node& node)
{
return node.attributes();
}
}
#endif

View file

@ -1,7 +1,7 @@
website <http://pugixml.org>; repository <http://github.com/zeux/pugixml>
website <https://pugixml.org>; repository <https://github.com/zeux/pugixml>
:toc: right
:source-highlighter: pygments
:source-language: c++
:sectanchors:
:sectlinks:
:imagesdir: images
:imagesdir: images

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,7 +4,7 @@ include::config.adoc[]
[[introduction]]
== Introduction
http://pugixml.org/[pugixml] is a light-weight C{plus}{plus} XML processing library. It consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with two Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving). The library is extremely portable and easy to integrate and use. pugixml is developed and maintained since 2006 and has many users. All code is distributed under the <<license,MIT license>>, making it completely free to use in both open-source and proprietary applications.
https://pugixml.org/[pugixml] is a light-weight C{plus}{plus} XML processing library. It consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with two Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving). The library is extremely portable and easy to integrate and use. pugixml is developed and maintained since 2006 and has many users. All code is distributed under the <<license,MIT license>>, making it completely free to use in both open-source and proprietary applications.
pugixml enables very fast, convenient and memory-efficient XML document processing. However, since pugixml has a DOM parser, it can't process XML documents that do not fit in memory; also the parser is a non-validating one, so if you need DTD/Schema validation, the library is not for you.
@ -24,8 +24,8 @@ https://github.com/zeux/pugixml/releases/download/v{version}/pugixml-{version}.t
The distribution contains library source, documentation (the guide you're reading now and the manual) and some code examples. After downloading the distribution, install pugixml by extracting all files from the compressed archive.
The complete pugixml source consists of three files - one source file, `pugixml.cpp`, and two header files, `pugixml.hpp` and `pugiconfig.hpp`. `pugixml.hpp` is the primary header which you need to include in order to use pugixml classes/functions. The rest of this guide assumes that `pugixml.hpp` is either in the current directory or in one of include directories of your projects, so that `#include "pugixml.hpp"` can find the header; however you can also use relative path (i.e. `#include "../libs/pugixml/src/pugixml.hpp"`) or include directory-relative path (i.e. `#include <xml/thirdparty/pugixml/src/pugixml.hpp>`).
The easiest way to build pugixml is to compile the source file, `pugixml.cpp`, along with the existing library/executable. This process depends on the method of building your application; for example, if you're using Microsoft Visual Studio footnote:[All trademarks used are properties of their respective owners.], Apple Xcode, Code::Blocks or any other IDE, just add `pugixml.cpp` to one of your projects. There are other building methods available, including building pugixml as a standalone static/shared library; link:manual/install.html#install.building[read the manual] for further information.
The easiest way to build pugixml is to compile the source file, `pugixml.cpp`, along with the existing library/executable. This process depends on the method of building your application; for example, if you're using Microsoft Visual Studio footnote:[All trademarks used are properties of their respective owners.], Apple Xcode, Code::Blocks or any other IDE, just *add `pugixml.cpp` to one of your projects*. There are other building methods available, including building pugixml as a standalone static/shared library; link:manual.html#install.building[read the manual] for further information.
[[dom]]
== Document object model
@ -54,7 +54,7 @@ There is a special value of `xml_node` type, known as null node or empty node. I
`xml_attribute` is the handle to an XML attribute; it has the same semantics as `xml_node`, i.e. there can be several `xml_attribute` handles pointing to the same underlying object and there is a special null attribute value, which propagates to function results.
There are two choices of interface and internal representation when configuring pugixml: you can either choose the UTF-8 (also called char) interface or UTF-16/32 (also called wchar_t) one. The choice is controlled via `PUGIXML_WCHAR_MODE` define; you can set it via `pugiconfig.hpp` or via preprocessor options. All tree functions that work with strings work with either C-style null terminated strings or STL strings of the selected character type. link:manual/dom.html#dom.unicode[Read the manual] for additional information on Unicode interface.
There are two choices of interface and internal representation when configuring pugixml: you can either choose the UTF-8 (also called char) interface or UTF-16/32 (also called wchar_t) one. The choice is controlled via `PUGIXML_WCHAR_MODE` define; you can set it via `pugiconfig.hpp` or via preprocessor options. All tree functions that work with strings work with either C-style null terminated strings or STL strings of the selected character type. link:manual.html#dom.unicode[Read the manual] for additional information on Unicode interface.
[[loading]]
== Loading document
@ -67,7 +67,7 @@ This is an example of loading XML document from file (link:samples/load_file.cpp
[source,indent=0]
----
include::samples/load_file.cpp[tags=code]
include::samples/load_file.cpp[tags=code]
----
`load_file`, as well as other loading functions, destroys the existing document tree and then tries to load the new tree from the specified file. The result of the operation is returned in an `xml_parse_result` object; this object contains the operation status, and the related information (i.e. last successfully parsed position in the input file, if parsing fails).
@ -78,7 +78,7 @@ This is an example of handling loading errors (link:samples/load_error_handling.
[source,indent=0]
----
include::samples/load_error_handling.cpp[tags=code]
include::samples/load_error_handling.cpp[tags=code]
----
Sometimes XML data should be loaded from some other source than file, i.e. HTTP URL; also you may want to load XML data from file using non-standard functions, i.e. to use your virtual file system facilities or to load XML from gzip-compressed files. These scenarios either require loading document from memory, in which case you should prepare a contiguous memory block with all XML data and to pass it to one of buffer loading functions, or loading document from C{plus}{plus} IOstream, in which case you should provide an object which implements `std::istream` or `std::wistream` interface.
@ -240,7 +240,7 @@ This is a simple example of custom writer for saving document data to STL string
include::samples/save_custom_writer.cpp[tags=code]
----
While the previously described functions save the whole document to the destination, it is easy to save a single subtree. Instead of calling `xml_document::save`, just call `xml_node::print` function on the target node. You can save node contents to C{plus}{plus} IOstream object or custom writer in this way. Saving a subtree slightly differs from saving the whole document; link:manual/saving.html#saving.subtree[read the manual] for more information.
While the previously described functions save the whole document to the destination, it is easy to save a single subtree. Instead of calling `xml_document::save`, just call `xml_node::print` function on the target node. You can save node contents to C{plus}{plus} IOstream object or custom writer in this way. Saving a subtree slightly differs from saving the whole document; link:manual.html#saving.subtree[read the manual] for more information.
[[feedback]]
== Feedback
@ -255,7 +255,7 @@ If filing an issue is not possible due to privacy or other concerns, you can con
The pugixml library is distributed under the MIT license:
....
Copyright (c) 2006-2015 Arseny Kapoulkine
Copyright (c) 2006-2022 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
@ -280,8 +280,8 @@ OTHER DEALINGS IN THE SOFTWARE.
....
This means that you can freely use pugixml in your applications, both open-source and proprietary. If you use pugixml in a product, it is sufficient to add an acknowledgment like this to the product distribution:
....
This software is based on pugixml library (https://pugixml.org).
pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine.
....
This software is based on pugixml library (http://pugixml.org).
pugixml is Copyright (C) 2006-2015 Arseny Kapoulkine.
....

File diff suppressed because it is too large Load diff

View file

@ -48,7 +48,7 @@ bool preprocess(pugi::xml_node node)
bool load_preprocess(pugi::xml_document& doc, const char* path)
{
pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for <?include?>
return result ? preprocess(doc) : false;
}
// end::code[]

View file

@ -15,7 +15,7 @@ int main()
decl.append_attribute("encoding") = "UTF-8";
decl.append_attribute("standalone") = "no";
// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
// <?xml version="1.0" encoding="UTF-8" standalone="no"?>
// <foo bar="baz">
// <call>hey</call>
// </foo>

View file

@ -1,7 +1,7 @@
pugixml 1.7 - an XML processing library
pugixml 1.13 - an XML processing library
Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
Report bugs and download new versions at http://pugixml.org/
Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
Report bugs and download new versions at https://pugixml.org/
This is the distribution of pugixml, which is a C++ XML processing library,
which consists of a DOM-like interface with rich traversal/modification
@ -13,8 +13,6 @@ automatically during parsing/saving).
The distribution contains the following folders:
contrib/ - various contributions to pugixml
docs/ - documentation
docs/samples - pugixml usage examples
docs/quickstart.html - quick start guide
@ -28,7 +26,7 @@ The distribution contains the following folders:
This library is distributed under the MIT License:
Copyright (c) 2006-2015 Arseny Kapoulkine
Copyright (c) 2006-2022 Arseny Kapoulkine
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

View file

@ -1,52 +0,0 @@
project(pugixml)
cmake_minimum_required(VERSION 2.6)
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
option(BUILD_TESTS "Build tests" OFF)
set(BUILD_DEFINES "" CACHE STRING "Build defines")
# Pre-defines standard install locations on *nix systems.
include(GNUInstallDirs)
mark_as_advanced(CLEAR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR)
set(HEADERS ../src/pugixml.hpp ../src/pugiconfig.hpp)
set(SOURCES ${HEADERS} ../src/pugixml.cpp)
if(DEFINED BUILD_DEFINES)
foreach(DEFINE ${BUILD_DEFINES})
add_definitions("-D" ${DEFINE})
endforeach()
endif()
if(BUILD_SHARED_LIBS)
add_library(pugixml SHARED ${SOURCES})
else()
add_library(pugixml STATIC ${SOURCES})
endif()
# Enable C++11 long long for compilers that are capable of it
if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} STRLESS 3.1)
target_compile_features(pugixml PUBLIC cxx_long_long_type)
endif()
set_target_properties(pugixml PROPERTIES VERSION 1.7 SOVERSION 1)
install(TARGETS pugixml EXPORT pugixml-config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT pugixml-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml)
if(BUILD_TESTS)
file(GLOB TEST_SOURCES ../tests/*.cpp)
file(GLOB FUZZ_SOURCES ../tests/fuzz_*.cpp)
list(REMOVE_ITEM TEST_SOURCES ${FUZZ_SOURCES})
add_executable(check ${TEST_SOURCES})
target_link_libraries(check pugixml)
add_custom_command(TARGET check POST_BUILD COMMAND check WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/..)
endif()

54
scripts/archive.py Normal file
View file

@ -0,0 +1,54 @@
import io
import os.path
import sys
import tarfile
import time
import zipfile
def read_file(path, use_crlf):
with open(path, 'rb') as file:
data = file.read()
if b'\0' not in data:
data = data.replace(b'\r', b'')
if use_crlf:
data = data.replace(b'\n', b'\r\n')
return data
def write_zip(target, arcprefix, timestamp, sources):
with zipfile.ZipFile(target, 'w') as archive:
for source in sorted(sources):
data = read_file(source, use_crlf = True)
path = os.path.join(arcprefix, source)
info = zipfile.ZipInfo(path)
info.date_time = time.localtime(timestamp)
info.compress_type = zipfile.ZIP_DEFLATED
info.external_attr = 0o644 << 16
archive.writestr(info, data)
def write_tar(target, arcprefix, timestamp, sources, compression):
with tarfile.open(target, 'w:' + compression) as archive:
for source in sorted(sources):
data = read_file(source, use_crlf = False)
path = os.path.join(arcprefix, source)
info = tarfile.TarInfo(path)
info.size = len(data)
info.mtime = timestamp
archive.addfile(info, io.BytesIO(data))
if len(sys.argv) < 5:
raise RuntimeError('Usage: python archive.py <target> <archive prefix> <timestamp> <source files>')
target, arcprefix, timestamp = sys.argv[1:4]
sources = sys.argv[4:]
# tarfile._Stream._init_write_gz always writes current time to gzip header
time.time = lambda: timestamp
if target.endswith('.zip'):
write_zip(target, arcprefix, int(timestamp), sources)
elif target.endswith('.tar.gz') or target.endswith('.tar.bz2'):
write_tar(target, arcprefix, int(timestamp), sources, compression = os.path.splitext(target)[1][1:])
else:
raise NotImplementedError('File type not supported: ' + target)

4
scripts/cocoapods_push.sh Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
#Push to igagis repo for now
pod repo push igagis pugixml.podspec --use-libraries --verbose

View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="pugi::xml_node">
<DisplayString Condition="_root">{_root}</DisplayString>
<DisplayString Condition="!_root">none</DisplayString>
<Expand>
<ExpandedItem Condition="_root">_root</ExpandedItem>
</Expand>
</Type>
<Type Name="pugi::xml_node_struct">
<DisplayString Condition="name &amp;&amp; value">{(pugi::xml_node_type)(header &amp; 0xf),en} name={name,na} value={value,na}</DisplayString>
<DisplayString Condition="name">{(pugi::xml_node_type)(header &amp; 0xf),en} name={name,na}</DisplayString>
<DisplayString Condition="value">{(pugi::xml_node_type)(header &amp; 0xf),en} value={value,na}</DisplayString>
<DisplayString>{(pugi::xml_node_type)(header &amp; 0xf),en}</DisplayString>
<Expand>
<Item Name="value" Condition="value">value,na</Item>
<Synthetic Name="attributes" Condition="first_attribute">
<Expand>
<CustomListItems>
<Variable Name="curr" InitialValue="first_attribute" />
<Loop Condition="curr">
<Item Name="{curr->name,na}">curr,view(child)na</Item>
<Exec>curr = curr->next_attribute</Exec>
</Loop>
</CustomListItems>
</Expand>
</Synthetic>
<LinkedListItems>
<HeadPointer>first_child</HeadPointer>
<NextPointer>next_sibling</NextPointer>
<ValueNode>this,na</ValueNode>
</LinkedListItems>
</Expand>
</Type>
<Type Name="pugi::xml_attribute">
<DisplayString Condition="_attr">{_attr}</DisplayString>
<DisplayString Condition="!_attr">none</DisplayString>
<Expand>
<ExpandedItem Condition="_attr">_attr</ExpandedItem>
</Expand>
</Type>
<Type Name="pugi::xml_attribute_struct">
<DisplayString ExcludeView="child">{name,na} = {value,na}</DisplayString>
<DisplayString>{value,na}</DisplayString>
<Expand>
<Item Name="name">name,na</Item>
<Item Name="value">value,na</Item>
</Expand>
</Type>
<Type Name="pugi::xpath_node">
<DisplayString Condition="_node._root &amp;&amp; _attribute._attr">{_node,na} "{_attribute._attr->name,na}"="{_attribute._attr->value,na}"</DisplayString>
<DisplayString Condition="_node._root">{_node,na}</DisplayString>
<DisplayString Condition="_attribute._attr">{_attribute}</DisplayString>
<DisplayString>empty</DisplayString>
<Expand HideRawView="1">
<ExpandedItem Condition="_node._root &amp;&amp; !_attribute._attr">_node</ExpandedItem>
<ExpandedItem Condition="!_node._root &amp;&amp; _attribute._attr">_attribute</ExpandedItem>
<Item Name="node" Condition="_node._root &amp;&amp; _attribute._attr">_node,na</Item>
<Item Name="attribute" Condition="_node._root &amp;&amp; _attribute._attr">_attribute,na</Item>
</Expand>
</Type>
<Type Name="pugi::xpath_node_set">
<Expand>
<Item Name="type">_type</Item>
<ArrayItems>
<Size>_end - _begin</Size>
<ValuePointer>_begin</ValuePointer>
</ArrayItems>
</Expand>
</Type>
</AutoVisualizer>

View file

@ -0,0 +1,506 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="pugi::xml_node">
<DisplayString Condition="_root">{_root}</DisplayString>
<DisplayString Condition="!_root">none</DisplayString>
<Expand>
<ExpandedItem Condition="_root">_root</ExpandedItem>
</Expand>
</Type>
<Type Name="pugi::xml_attribute">
<DisplayString Condition="_attr">{_attr}</DisplayString>
<DisplayString Condition="!_attr">none</DisplayString>
<Expand>
<ExpandedItem Condition="_attr">_attr</ExpandedItem>
</Expand>
</Type>
<Type Name="pugi::xml_node_struct">
<Expand>
<Item Name="type">(pugi::xml_node_type)(header._flags &amp; 15)</Item>
<Item Name="name" Condition="name._data">name,na</Item>
<Item Name="value" Condition="value._data">value,na</Item>
<Synthetic Name="attributes" Condition="first_attribute._data">
<DisplayString>...</DisplayString>
<Expand>
<CustomListItems>
<Variable Name="attribute_this" InitialValue="(size_t)&amp;first_attribute" />
<Variable Name="attribute_data" InitialValue="first_attribute._data" />
<Variable Name="attribute_data_copy" InitialValue="attribute_data" />
<!-- first_attribute struct template arguments -->
<Variable Name="attribute_T1" InitialValue="11" />
<Variable Name="attribute_T2" InitialValue="0" />
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(attribute_this - attribute_T1)" />
<Variable Name="page" InitialValue="((attribute_this - attribute_T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(attribute_this - attribute_T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)attribute_this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<Variable Name="attribute_real" InitialValue="(pugi::xml_attribute_struct*)0" />
<!-- if _data < 255 -->
<Variable Name="attribute_short" InitialValue="(pugi::xml_attribute_struct*)(((size_t)attribute_this &amp; ~(compact_alignment - 1)) + (attribute_data - 1 + attribute_T2) * compact_alignment)" />
<Variable Name="number" InitialValue="0" />
<!-- Loop over all attributes -->
<Loop Condition="attribute_this &amp;&amp; attribute_data">
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == attribute_this || *probe_item == 0">
<Exec>attribute_real = *(pugi::xml_attribute_struct**)(probe_item + 1)</Exec><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
<Exec>attribute_data_copy = attribute_data</Exec>
<If Condition="attribute_data_copy &gt;= 255 &amp;&amp; attribute_real">
<Item Name="[{number}]">*attribute_real,view(child)</Item>
<Exec>attribute_this = (size_t)&amp;(*attribute_real).next_attribute</Exec>
<Exec>attribute_data = (*attribute_real).next_attribute._data</Exec>
</If>
<If Condition="attribute_data_copy &lt; 255 &amp;&amp; attribute_short">
<Item Name="[{number}]">*attribute_short,view(child)</Item>
<Exec>attribute_this = (size_t)&amp;(*attribute_short).next_attribute</Exec>
<Exec>attribute_data = (*attribute_short).next_attribute._data</Exec>
</If>
<!-- next_attribute struct template arguments -->
<Exec>attribute_T1 = 7</Exec>
<Exec>attribute_T2 = 0</Exec>
<!-- find() prolog again -->
<Exec>h = (unsigned)attribute_this</Exec>
<Exec>bucket = 0</Exec>
<Exec>probe = 0</Exec>
<Exec>probe_item = (size_t*)0</Exec>
<Exec>attribute_real = (pugi::xml_attribute_struct*)0</Exec>
<Exec>attribute_short = (pugi::xml_attribute_struct*)(((size_t)attribute_this &amp; ~(compact_alignment - 1)) + (attribute_data - 1 + attribute_T2) * compact_alignment)</Exec>
<Exec>number++</Exec>
</Loop>
</CustomListItems>
</Expand>
</Synthetic>
<CustomListItems>
<Variable Name="child_this" InitialValue="&amp;first_child" />
<Variable Name="child_data" InitialValue="first_child._data" />
<Variable Name="child_data_copy" InitialValue="child_data" />
<!-- first_child struct template arguments -->
<Variable Name="child_T1" InitialValue="8" />
<Variable Name="child_T2" InitialValue="0" />
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(child_this - child_T1)" />
<Variable Name="page" InitialValue="((child_this - child_T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(child_this - child_T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)child_this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<Variable Name="child_real" InitialValue="(pugi::xml_node_struct*)0" />
<!-- if _data < 255 -->
<Variable Name="child_short" InitialValue="(pugi::xml_node_struct*)(((size_t)child_this &amp; ~(compact_alignment - 1)) + (child_data - 1 + child_T2) * compact_alignment)" />
<Variable Name="number" InitialValue="0" />
<Loop Condition="child_this &amp;&amp; child_data">
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == child_this || *probe_item == 0">
<Exec>child_real = *(pugi::xml_node_struct**)(probe_item + 1)</Exec><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
<Exec>child_data_copy = child_data</Exec>
<If Condition="child_data_copy &gt;= 255 &amp;&amp; child_real">
<Item Name="[{number}]">*child_real,view(child)</Item>
<Exec>child_this = (size_t)&amp;(*child_real).next_sibling</Exec>
<Exec>child_data = (*child_real).next_sibling._data</Exec>
</If>
<If Condition="child_data_copy &lt; 255 &amp;&amp; child_short">
<Item Name="[{number}]">*child_short,view(child)</Item>
<Exec>child_this = (size_t)&amp;(*child_short).next_sibling</Exec>
<Exec>child_data = (*child_short).next_sibling._data</Exec>
</If>
<!-- next_sibling struct template arguments -->
<Exec>child_T1 = 10</Exec>
<Exec>child_T2 = 0</Exec>
<!-- find() prolog again -->
<Exec>h = (unsigned)child_this</Exec>
<Exec>bucket = 0</Exec>
<Exec>probe = 0</Exec>
<Exec>probe_item = (size_t*)0</Exec>
<Exec>child_real = (pugi::xml_node_struct*)0</Exec>
<Exec>child_short = (pugi::xml_node_struct*)(((size_t)child_this &amp; ~(compact_alignment - 1)) + (child_data - 1 + child_T2) * compact_alignment)</Exec>
<Exec>number++</Exec>
</Loop>
</CustomListItems>
<Item Name="next_sibling" ExcludeView="child">next_sibling</Item>
</Expand>
</Type>
<Type Name="pugi::xml_attribute_struct">
<Expand>
<Item Name="name">name,na</Item>
<Item Name="value">value,na</Item>
<CustomListItems ExcludeView="child">
<Variable Name="attribute_this" InitialValue="&amp;next_attribute" />
<Variable Name="attribute_data" InitialValue="next_attribute._data" />
<!-- next_attribute struct template arguments -->
<Variable Name="attribute_T1" InitialValue="7" />
<Variable Name="attribute_T2" InitialValue="0" />
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(attribute_this - attribute_T1)" />
<Variable Name="page" InitialValue="((attribute_this - attribute_T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(attribute_this - attribute_T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)attribute_this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<Variable Name="attribute_real" InitialValue="(pugi::xml_attribute_struct*)0" />
<!-- if _data < 255 -->
<Variable Name="attribute_short" InitialValue="(pugi::xml_attribute_struct*)(((size_t)attribute_this &amp; ~(compact_alignment - 1)) + (attribute_data - 1 + attribute_T2) * compact_alignment)" />
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == attribute_this || *probe_item == 0">
<Exec>attribute_real = *(pugi::xml_attribute_struct**)(probe_item + 1)</Exec><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
<If Condition="attribute_data &gt;= 255 &amp;&amp; attribute_real">
<Item Name="next_attribute">*attribute_real</Item>
</If>
<If Condition="attribute_data != 0 &amp;&amp; attribute_data &lt; 255 &amp;&amp; attribute_short">
<Item Name="next_attribute">*attribute_short</Item>
</If>
</CustomListItems>
</Expand>
</Type>
<Type Name="pugi::impl::`anonymous-namespace'::compact_string&lt;*,*&gt;">
<Expand HideRawView="1">
<CustomListItems Condition="_data &amp;&amp; _data &lt; 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
<Variable Name="page" InitialValue="((this - $T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<Variable Name="compact_string_base" InitialValue="*(size_t*)(page + 5 * sizeof(void*))" /><!-- 5 pointer offsetof(page, compact_string_base)-->
<Variable Name="base" InitialValue="this - $T2" />
<Variable Name="offset" InitialValue="((*(short*)base - 1) &lt;&lt; 7) + (_data - 1)" />
<Item Name="value">(pugi::char_t*)(compact_string_base + offset * sizeof(pugi::char_t)),na</Item>
</CustomListItems>
<CustomListItems Condition="_data &amp;&amp; _data &gt;= 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
<Variable Name="page" InitialValue="((this - $T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == this || *probe_item == 0">
<Item Name="value">*(pugi::char_t**)(probe_item + 1)</Item><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
</CustomListItems>
</Expand>
</Type>
<Type Name="pugi::impl::`anonymous-namespace'::compact_pointer&lt;pugi::xml_node_struct,*,*&gt;">
<DisplayString Condition="!_data">nullptr</DisplayString>
<DisplayString Condition="_data">...</DisplayString>
<Expand HideRawView="1">
<CustomListItems Condition="_data &amp;&amp; _data &lt; 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<Item Name="value">*(pugi::xml_node_struct*)(((size_t)this &amp; ~(compact_alignment - 1)) + (_data - 1 + $T2) * compact_alignment)</Item>
</CustomListItems>
<CustomListItems Condition="_data &amp;&amp; _data &gt;= 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
<Variable Name="page" InitialValue="((this - $T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == this || *probe_item == 0">
<Item Name="value">**(pugi::xml_node_struct**)(probe_item + 1)</Item><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
</CustomListItems>
</Expand>
</Type>
<Type Name="pugi::impl::`anonymous-namespace'::compact_pointer&lt;pugi::xml_attribute_struct,*,*&gt;">
<DisplayString Condition="!_data">nullptr</DisplayString>
<DisplayString Condition="_data">...</DisplayString>
<Expand HideRawView="1">
<CustomListItems Condition="_data &amp;&amp; _data &lt; 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<Item Name="value">*(pugi::xml_attribute_struct*)(((size_t)this &amp; ~(compact_alignment - 1)) + (_data - 1 + $T2) * compact_alignment)</Item>
</CustomListItems>
<CustomListItems Condition="_data &amp;&amp; _data &gt;= 255">
<Variable Name="compact_alignment_log2" InitialValue="2" />
<Variable Name="compact_alignment" InitialValue="1 &lt;&lt; compact_alignment_log2" />
<!-- compact_get_page() -->
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
<Variable Name="page" InitialValue="((this - $T1 - (_page &lt;&lt; compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page &lt;&lt; compact_alignment_log2)))" />
<!-- page->allocator->_hash -->
<Variable Name="allocator" InitialValue="*(size_t*)page" />
<Variable Name="_hash" InitialValue="*(size_t*)(allocator + 2 * sizeof(size_t))" /><!--2 pointer offsetof(allocator, _hash)-->
<Variable Name="_items" InitialValue="*(size_t*)_hash" />
<Variable Name="_capacity" InitialValue="*((size_t*)_hash + 1)" /><!--1 pointer offsetof(_hash, _capacity)-->
<Variable Name="_count" InitialValue="*((size_t*)_hash + 2)" /><!--2 pointer offsetof(_hash, _count)-->
<!-- find() prolog -->
<Variable Name="hashmod" InitialValue="_capacity - 1" />
<Variable Name="h" InitialValue="(unsigned)this" />
<Variable Name="bucket" InitialValue="0" />
<Variable Name="probe" InitialValue="0" />
<Variable Name="probe_item" InitialValue="(size_t*)0" />
<!-- find() hash -->
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>h = h * (0x85ebca6bu)</Exec>
<Exec>h = h ^ (h >> 13)</Exec>
<Exec>h = h * (0xc2b2ae35u)</Exec>
<Exec>h = h ^ (h >> 16)</Exec>
<Exec>bucket = h &amp; hashmod</Exec>
<!-- find() loop -->
<Loop Condition="probe &lt;= hashmod &amp;&amp;_capacity">
<Exec>probe_item = (size_t*)_items + bucket * 2</Exec><!--2 pointer sizeof(item_t)-->
<If Condition="*probe_item == this || *probe_item == 0">
<Item Name="value">**(pugi::xml_attribute_struct**)(probe_item + 1)</Item><!--1 pointer offsetof(item_t, value)-->
<Break/>
</If>
<Exec>bucket = (bucket + probe + 1) &amp; hashmod</Exec>
<Exec>probe++</Exec>
</Loop>
</CustomListItems>
</Expand>
</Type>
<Type Name="pugi::xpath_node">
<DisplayString Condition="_node._root &amp;&amp; _attribute._attr">{_node,na} {_attribute,na}</DisplayString>
<DisplayString Condition="_node._root">{_node,na}</DisplayString>
<DisplayString Condition="_attribute._attr">{_attribute}</DisplayString>
<DisplayString>empty</DisplayString>
<Expand HideRawView="1">
<ExpandedItem Condition="_node._root &amp;&amp; !_attribute._attr">_node</ExpandedItem>
<ExpandedItem Condition="!_node._root &amp;&amp; _attribute._attr">_attribute</ExpandedItem>
<Item Name="node" Condition="_node._root &amp;&amp; _attribute._attr">_node,na</Item>
<Item Name="attribute" Condition="_node._root &amp;&amp; _attribute._attr">_attribute,na</Item>
</Expand>
</Type>
<Type Name="pugi::xpath_node_set">
<Expand>
<Item Name="type">_type</Item>
<ArrayItems>
<Size>_end - _begin</Size>
<ValuePointer>_begin</ValuePointer>
</ArrayItems>
</Expand>
</Type>
</AutoVisualizer>

View file

@ -1,32 +0,0 @@
nuget {
nuspec {
id = pugixml;
version: 1.7.0;
authors: {Arseny Kapoulkine};
owners: {Arseny Kapoulkine};
projectUrl: "http://pugixml.org/";
iconUrl: "https://github.com/zeux/pugixml/logo.svg";
title: pugixml;
summary: "Light-weight, simple and fast XML parser for C++ with XPath support";
releaseNotes: "http://pugixml.org/docs/manual.html#changes";
copyright: "Copyright (c) 2006-2015 Arseny Kapoulkine";
licenseUrl: "http://pugixml.org/license.html";
requireLicenseAcceptance: false;
description: @"pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving).
pugixml is used by a lot of projects, both open-source and proprietary, for performance and easy-to-use interface.";
tags: { native };
}
files {
include: { "..\src\*.hpp" };
[x86,release] { lib: vs2015\Win32_Release\pugixml.lib; }
[x86,debug] { lib: vs2015\Win32_Debug\pugixml.lib; }
[x64,release] { lib: vs2015\x64_Release\pugixml.lib; }
[x64,debug] { lib: vs2015\x64_Debug\pugixml.lib; }
}
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework">
<Rule Name="ReferencedPackages05032e35-86af-4ab2-a3dc-d3e348583165" PageTemplate="tool" DisplayName="Referenced Packages" SwitchPrefix="/" Order="1">
<Rule.Categories>
<Category Name="pugixml" DisplayName="pugixml" />
</Rule.Categories>
<Rule.DataSource>
<DataSource Persistence="ProjectFile" ItemType="" />
</Rule.DataSource>
<EnumProperty Name="Linkage-pugixml" DisplayName="Linkage" Description="Which version of the runtime library to use for this library" Category="pugixml">
<EnumValue Name="dynamic" DisplayName="Dynamic CRT (/MD, /MDd)" />
<EnumValue Name="static" DisplayName="Static CRT (/MT, /MTd)" />
<EnumValue Name="source" DisplayName="Include pugixml.cpp" />
<EnumValue Name="header" DisplayName="Header Only" />
</EnumProperty>
</Rule>
</ProjectSchemaDefinitions>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Default initializers for properties">
<Linkage-pugixml Condition="'$(Linkage-pugixml)' == ''">dynamic</Linkage-pugixml>
<Configuration-pugixml Condition="$(Configuration.ToLower().IndexOf('debug')) != -1">Debug</Configuration-pugixml>
<Configuration-pugixml Condition="$(Configuration.ToLower().IndexOf('debug')) == -1">Release</Configuration-pugixml>
</PropertyGroup>
<ItemGroup>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)\pugixml-propertiesui.xml" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions Condition="'$(Linkage-pugixml)' == 'header'">PUGIXML_HEADER_ONLY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup Condition="'$(Linkage-pugixml)' == 'source'">
<ClCompile Include="$(MSBuildThisFileDirectory)include\pugixml.cpp"/>
</ItemGroup>
<ItemDefinitionGroup Condition="'$(Linkage-pugixml)' != 'header' AND '$(Linkage-pugixml)' != 'source'">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/$(Platform)\$(PlatformToolset.Split('_')[0])\$(Linkage-pugixml)\$(Configuration-pugixml)\pugixml.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
</Project>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
<metadata>
<id>pugixml</id>
<version>1.13.0-appveyor</version>
<title>pugixml</title>
<authors>Arseny Kapoulkine</authors>
<owners>Arseny Kapoulkine</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://pugixml.org/</projectUrl>
<description>pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving).
pugixml is used by a lot of projects, both open-source and proprietary, for performance and easy-to-use interface.
This package contains builds for VS2013, VS2015, VS2017, VS2019 and VS2022, for both statically linked and DLL CRT; you can switch the CRT linkage in Project -> Properties -> Referenced Packages -> pugixml.</description>
<summary>Light-weight, simple and fast XML parser for C++ with XPath support</summary>
<releaseNotes>https://pugixml.org/docs/manual.html#changes</releaseNotes>
<copyright>Copyright (c) 2006-2022 Arseny Kapoulkine</copyright>
<tags>native nativepackage</tags>
</metadata>
</package>

View file

@ -1,8 +0,0 @@
@echo off
"%VS140COMNTOOLS%\VsMSBuildCmd.bat" && ^
msbuild pugixml_vs2015.vcxproj /t:Rebuild /p:Configuration=Debug /p:Platform=x86 /v:minimal /nologo && ^
msbuild pugixml_vs2015.vcxproj /t:Rebuild /p:Configuration=Release /p:Platform=x86 /v:minimal /nologo && ^
msbuild pugixml_vs2015.vcxproj /t:Rebuild /p:Configuration=Debug /p:Platform=x64 /v:minimal /nologo && ^
msbuild pugixml_vs2015.vcxproj /t:Rebuild /p:Configuration=Release /p:Platform=x64 /v:minimal /nologo && ^
powershell Write-NuGetPackage nuget.autopkg

70
scripts/nuget_build.ps1 Normal file
View file

@ -0,0 +1,70 @@
function Run-Command([string]$cmd)
{
Invoke-Expression $cmd
if ($LastExitCode) { exit $LastExitCode }
}
function Force-Copy([string]$from, [string]$to)
{
Write-Host $from "->" $to
New-Item -Force $to | Out-Null
Copy-Item -Force $from $to
if (! $?) { exit 1 }
}
function Build-Version([string]$vs, [string]$toolset, [string]$linkage)
{
$prjsuffix = if ($linkage -eq "static") { "_static" } else { "" }
$cfgsuffix = if ($linkage -eq "static") { "Static" } else { "" }
foreach ($configuration in "Debug","Release")
{
Run-Command "msbuild pugixml_$vs$prjsuffix.vcxproj /t:Rebuild /p:Configuration=$configuration /p:Platform=x86 /v:minimal /nologo"
Run-Command "msbuild pugixml_$vs$prjsuffix.vcxproj /t:Rebuild /p:Configuration=$configuration /p:Platform=x64 /v:minimal /nologo"
Force-Copy "$vs/Win32_$configuration$cfgsuffix/pugixml.lib" "nuget/build/native/lib/Win32/$toolset/$linkage/$configuration/pugixml.lib"
Force-Copy "$vs/x64_$configuration$cfgsuffix/pugixml.lib" "nuget/build/native/lib/x64/$toolset/$linkage/$configuration/pugixml.lib"
}
}
Push-Location
$scriptdir = Split-Path $MyInvocation.MyCommand.Path
cd $scriptdir
Force-Copy "../src/pugiconfig.hpp" "nuget/build/native/include/pugiconfig.hpp"
Force-Copy "../src/pugixml.hpp" "nuget/build/native/include/pugixml.hpp"
Force-Copy "../src/pugixml.cpp" "nuget/build/native/include/pugixml.cpp"
if ($args[0] -eq 2022){
Build-Version "vs2022" "v143" "dynamic"
Build-Version "vs2022" "v143" "static"
} elseif ($args[0] -eq 2019){
Build-Version "vs2019" "v142" "dynamic"
Build-Version "vs2019" "v142" "static"
} elseif ($args[0] -eq 2017){
Build-Version "vs2017" "v141" "dynamic"
Build-Version "vs2017" "v141" "static"
Build-Version "vs2015" "v140" "dynamic"
Build-Version "vs2015" "v140" "static"
Build-Version "vs2013" "v120" "dynamic"
Build-Version "vs2013" "v120" "static"
} elseif($args[0] -eq 2015){
Build-Version "vs2015" "v140" "dynamic"
Build-Version "vs2015" "v140" "static"
Build-Version "vs2013" "v120" "dynamic"
Build-Version "vs2013" "v120" "static"
} elseif($args[0] -eq 2013){
Build-Version "vs2013" "v120" "dynamic"
Build-Version "vs2013" "v120" "static"
}
Run-Command "nuget pack nuget"
Pop-Location

View file

@ -0,0 +1,12 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/pugixml-targets.cmake")
# If the user is not requiring 1.11 (either by explicitly requesting an older
# version or not requesting one at all), provide the old imported target name
# for compatibility.
if (NOT TARGET pugixml AND (NOT DEFINED PACKAGE_FIND_VERSION OR PACKAGE_FIND_VERSION VERSION_LESS "1.11"))
add_library(pugixml INTERFACE IMPORTED)
# Equivalent to target_link_libraries INTERFACE, but compatible with CMake 3.10
set_target_properties(pugixml PROPERTIES INTERFACE_LINK_LIBRARIES pugixml::pugixml)
endif ()

11
scripts/pugixml.pc.in Normal file
View file

@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@@INSTALL_SUFFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@@INSTALL_SUFFIX@
Name: pugixml
Description: Light-weight, simple and fast XML parser for C++ with XPath support.
URL: https://pugixml.org/
Version: @pugixml_VERSION@
Cflags: -I${includedir}
Libs: -L${libdir} -lpugixml@LIB_POSTFIX@

14
scripts/pugixml.podspec Normal file
View file

@ -0,0 +1,14 @@
Pod::Spec.new do |s|
s.name = "pugixml"
s.version = "1.13"
s.summary = "C++ XML parser library."
s.homepage = "https://pugixml.org"
s.license = "MIT"
s.author = { "Arseny Kapoulkine" => "arseny.kapoulkine@gmail.com" }
s.platform = :ios, "7.0"
s.source = { :git => "https://github.com/zeux/pugixml.git", :tag => "v" + s.version.to_s }
s.source_files = "src/**/*.{hpp,cpp}"
s.header_mappings_dir = "src"
end

45
scripts/pugixml_dll.rc Normal file
View file

@ -0,0 +1,45 @@
#include <winver.h>
#define PUGIXML_VERSION_MAJOR 1
#define PUGIXML_VERSION_MINOR 13
#define PUGIXML_VERSION_PATCH 0
#define PUGIXML_VERSION_NUMBER "1.13.0\0"
#if defined(GCC_WINDRES) || defined(__MINGW32__) || defined(__CYGWIN__)
VS_VERSION_INFO VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
#endif
FILEVERSION PUGIXML_VERSION_MAJOR,PUGIXML_VERSION_MINOR,PUGIXML_VERSION_PATCH,0
PRODUCTVERSION PUGIXML_VERSION_MAJOR,PUGIXML_VERSION_MINOR,PUGIXML_VERSION_PATCH,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS 1
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0 // not used
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
VALUE "CompanyName", "zeux/pugixml\0"
VALUE "FileDescription", "pugixml library\0"
VALUE "FileVersion", PUGIXML_VERSION_NUMBER
VALUE "InternalName", "pugixml.dll\0"
VALUE "LegalCopyright", "Copyright (C) 2006-2022, by Arseny Kapoulkine\0"
VALUE "OriginalFilename", "pugixml.dll\0"
VALUE "ProductName", "pugixml\0"
VALUE "ProductVersion", PUGIXML_VERSION_NUMBER
VALUE "Comments", "For more information visit https://github.com/zeux/pugixml/\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 1252
END
END

View file

@ -64,17 +64,17 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\x32\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\x32\Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixmld</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64\Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixmld</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\x32\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\x32\Release\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\Win32_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\Win32_Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64_Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\Win32_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\Win32_Release\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64\Release\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64_Release\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -93,12 +93,12 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmld.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixmld.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -117,12 +117,12 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmld.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixmld.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">

View file

@ -64,18 +64,18 @@
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\x32\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\x32\DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixmlsd</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64\DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixmlsd</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\x32\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\x32\ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pugixmls</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64\ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pugixmls</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\Win32_DebugStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2010\Win32_DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64_DebugStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2010\x64_DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\Win32_ReleaseStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2010\Win32_ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64_ReleaseStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2010\x64_ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -93,12 +93,12 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmlsd.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixmlsd.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -117,12 +117,12 @@
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmlsd.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixmlsd.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -141,14 +141,14 @@
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmls.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixmls.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -167,14 +167,14 @@
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixmls.lib</OutputFile>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixmls.pdb</ProgramDataBaseFileName>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View file

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{89A1E353-E2DC-495C-B403-742BE206ACED}</ProjectGuid>
<RootNamespace>pugixml</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2013\Win32_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2013\Win32_Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2013\x64_Debug\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2013\x64_Debug\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2013\Win32_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2013\Win32_Release\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2013\x64_Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2013\x64_Release\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugixml.hpp" />
<ClInclude Include="..\src\pugiconfig.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp">
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{89A1E353-E2DC-495C-B403-742BE206ACED}</ProjectGuid>
<RootNamespace>pugixml</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2013\Win32_DebugStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">vs2013\Win32_DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2013\x64_DebugStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">vs2013\x64_DebugStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2013\Win32_ReleaseStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">vs2013\Win32_ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">pugixml</TargetName>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2013\x64_ReleaseStatic\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">vs2013\x64_ReleaseStatic\</IntDir>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>Full</Optimization>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)pugixml.lib</OutputFile>
</Lib>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<ProgramDataBaseFileName>$(OutDir)pugixml.pdb</ProgramDataBaseFileName>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugixml.hpp" />
<ClInclude Include="..\src\pugiconfig.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp">
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2015\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2015\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2015\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2015\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2015\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2015\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2015\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2015\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2017\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2017\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2017\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2017\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2017\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2017\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2017\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2017\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2017\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2019\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2019\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2019\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2019\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2019\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2019\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2019\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2019\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2019\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2022\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2022\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2022\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2022\$(Platform)_$(Configuration)\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,176 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>pugixml</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>false</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>vs2022\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>vs2022\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>vs2022\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>vs2022\$(Platform)_$(Configuration)Static\</OutDir>
<IntDir>vs2022\$(Platform)_$(Configuration)Static\</IntDir>
<TargetName>pugixml</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<DebugInformationFormat>OldStyle</DebugInformationFormat>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\src\pugiconfig.hpp" />
<ClInclude Include="..\src\pugixml.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\pugixml.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -1,8 +1,8 @@
/**
* pugixml parser - version 1.7
* pugixml parser - version 1.13
* --------------------------------------------------------
* Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at http://pugixml.org/
* Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at https://pugixml.org/
*
* This library is distributed under the MIT License. See notice at the end
* of this file.
@ -40,6 +40,9 @@
// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
// Tune this constant to adjust max nesting for XPath queries
// #define PUGIXML_XPATH_DEPTH_LIMIT 1024
// Uncomment this to switch to header-only version
// #define PUGIXML_HEADER_ONLY
@ -49,7 +52,7 @@
#endif
/**
* Copyright (c) 2006-2015 Arseny Kapoulkine
* Copyright (c) 2006-2022 Arseny Kapoulkine
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -62,7 +65,7 @@
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,8 @@
/**
* pugixml parser - version 1.7
* pugixml parser - version 1.13
* --------------------------------------------------------
* Copyright (C) 2006-2015, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at http://pugixml.org/
* Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at https://pugixml.org/
*
* This library is distributed under the MIT License. See notice at the end
* of this file.
@ -11,9 +11,10 @@
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
*/
// Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons
// Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits
#ifndef PUGIXML_VERSION
// Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons
# define PUGIXML_VERSION 170
# define PUGIXML_VERSION 1130 // 1.13
#endif
// Include user configuration file (this can define various configuration macros)
@ -72,6 +73,55 @@
# endif
#endif
// If the platform is known to have move semantics support, compile move ctor/operator implementation
#ifndef PUGIXML_HAS_MOVE
# if __cplusplus >= 201103
# define PUGIXML_HAS_MOVE
# elif defined(_MSC_VER) && _MSC_VER >= 1600
# define PUGIXML_HAS_MOVE
# endif
#endif
// If C++ is 2011 or higher, add 'noexcept' specifiers
#ifndef PUGIXML_NOEXCEPT
# if __cplusplus >= 201103
# define PUGIXML_NOEXCEPT noexcept
# elif defined(_MSC_VER) && _MSC_VER >= 1900
# define PUGIXML_NOEXCEPT noexcept
# else
# define PUGIXML_NOEXCEPT
# endif
#endif
// Some functions can not be noexcept in compact mode
#ifdef PUGIXML_COMPACT
# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT
#else
# define PUGIXML_NOEXCEPT_IF_NOT_COMPACT PUGIXML_NOEXCEPT
#endif
// If C++ is 2011 or higher, add 'override' qualifiers
#ifndef PUGIXML_OVERRIDE
# if __cplusplus >= 201103
# define PUGIXML_OVERRIDE override
# elif defined(_MSC_VER) && _MSC_VER >= 1700
# define PUGIXML_OVERRIDE override
# else
# define PUGIXML_OVERRIDE
# endif
#endif
// If C++ is 2011 or higher, use 'nullptr'
#ifndef PUGIXML_NULL
# if __cplusplus >= 201103
# define PUGIXML_NULL nullptr
# elif defined(_MSC_VER) && _MSC_VER >= 1600
# define PUGIXML_NULL nullptr
# else
# define PUGIXML_NULL 0
# endif
#endif
// Character interface macros
#ifdef PUGIXML_WCHAR_MODE
# define PUGIXML_TEXT(t) L ## t
@ -133,13 +183,13 @@ namespace pugi
// This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default.
const unsigned int parse_eol = 0x0020;
// This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default.
const unsigned int parse_wconv_attribute = 0x0040;
// This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default.
const unsigned int parse_wnorm_attribute = 0x0080;
// This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default.
const unsigned int parse_declaration = 0x0100;
@ -158,6 +208,11 @@ namespace pugi
// is a valid document. This flag is off by default.
const unsigned int parse_fragment = 0x1000;
// This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of
// the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments.
// This flag is off by default.
const unsigned int parse_embed_pcdata = 0x2000;
// The default parsing mode.
// Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded,
// End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
@ -184,16 +239,16 @@ namespace pugi
};
// Formatting flags
// Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default.
const unsigned int format_indent = 0x01;
// Write encoding-specific BOM to the output stream. This flag is off by default.
const unsigned int format_write_bom = 0x02;
// Use raw output mode (no indentation and no line breaks are written). This flag is off by default.
const unsigned int format_raw = 0x04;
// Omit default XML declaration even if there is no declaration in the document. This flag is off by default.
const unsigned int format_no_declaration = 0x08;
@ -206,10 +261,22 @@ namespace pugi
// Write every attribute on a new line with appropriate indentation. This flag is off by default.
const unsigned int format_indent_attributes = 0x40;
// Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default.
const unsigned int format_no_empty_element_tags = 0x80;
// Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default.
const unsigned int format_skip_control_chars = 0x100;
// Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default.
const unsigned int format_attribute_single_quote = 0x200;
// The default set of formatting flags.
// Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none.
const unsigned int format_default = format_indent;
const int default_double_precision = 17;
const int default_float_precision = 9;
// Forward declarations
struct xml_attribute_struct;
struct xml_node_struct;
@ -225,7 +292,7 @@ namespace pugi
class xml_node;
class xml_text;
#ifndef PUGIXML_NO_XPATH
class xpath_node;
class xpath_node_set;
@ -247,6 +314,8 @@ namespace pugi
It begin() const { return _begin; }
It end() const { return _end; }
bool empty() const { return _begin == _end; }
private:
It _begin, _end;
};
@ -268,7 +337,7 @@ namespace pugi
// Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio
xml_writer_file(void* file);
virtual void write(const void* data, size_t size);
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
private:
void* file;
@ -283,7 +352,7 @@ namespace pugi
xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream);
xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream);
virtual void write(const void* data, size_t size);
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
private:
std::basic_ostream<char, std::char_traits<char> >* narrow_stream;
@ -299,13 +368,13 @@ namespace pugi
private:
xml_attribute_struct* _attr;
typedef void (*unspecified_bool_type)(xml_attribute***);
public:
// Default constructor. Constructs an empty attribute.
xml_attribute();
// Constructs attribute from internal pointer
explicit xml_attribute(xml_attribute_struct* attr);
@ -349,13 +418,18 @@ namespace pugi
// Set attribute name/value (returns false if attribute is empty or there is not enough memory)
bool set_name(const char_t* rhs);
bool set_value(const char_t* rhs, size_t sz);
bool set_value(const char_t* rhs);
// Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
bool set_value(int rhs);
bool set_value(unsigned int rhs);
bool set_value(long rhs);
bool set_value(unsigned long rhs);
bool set_value(double rhs);
bool set_value(double rhs, int precision);
bool set_value(float rhs);
bool set_value(float rhs, int precision);
bool set_value(bool rhs);
#ifdef PUGIXML_HAS_LONG_LONG
@ -367,6 +441,8 @@ namespace pugi
xml_attribute& operator=(const char_t* rhs);
xml_attribute& operator=(int rhs);
xml_attribute& operator=(unsigned int rhs);
xml_attribute& operator=(long rhs);
xml_attribute& operator=(unsigned long rhs);
xml_attribute& operator=(double rhs);
xml_attribute& operator=(float rhs);
xml_attribute& operator=(bool rhs);
@ -417,7 +493,7 @@ namespace pugi
// Borland C++ workaround
bool operator!() const;
// Comparison operators (compares wrapped node pointers)
bool operator==(const xml_node& r) const;
bool operator!=(const xml_node& r) const;
@ -438,7 +514,7 @@ namespace pugi
// Get node value, or "" if node is empty or it has no value
// Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes.
const char_t* value() const;
// Get attribute list
xml_attribute first_attribute() const;
xml_attribute last_attribute() const;
@ -450,7 +526,7 @@ namespace pugi
// Get next/previous sibling in the children list of the parent node
xml_node next_sibling() const;
xml_node previous_sibling() const;
// Get parent node
xml_node parent() const;
@ -477,8 +553,9 @@ namespace pugi
// Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value)
bool set_name(const char_t* rhs);
bool set_value(const char_t* rhs, size_t sz);
bool set_value(const char_t* rhs);
// Add attribute with specified name. Returns added attribute, or empty attribute on errors.
xml_attribute append_attribute(const char_t* name);
xml_attribute prepend_attribute(const char_t* name);
@ -519,10 +596,16 @@ namespace pugi
bool remove_attribute(const xml_attribute& a);
bool remove_attribute(const char_t* name);
// Remove all attributes
bool remove_attributes();
// Remove specified child
bool remove_child(const xml_node& n);
bool remove_child(const char_t* name);
// Remove all children
bool remove_children();
// Parses buffer as an XML document fragment and appends all nodes as children of the current node.
// Copies/converts the buffer, so it may be deleted or changed after the function returns.
// Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory.
@ -532,11 +615,11 @@ namespace pugi
template <typename Predicate> xml_attribute find_attribute(Predicate pred) const
{
if (!_root) return xml_attribute();
for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute())
if (pred(attrib))
return attrib;
return xml_attribute();
}
@ -544,11 +627,11 @@ namespace pugi
template <typename Predicate> xml_node find_child(Predicate pred) const
{
if (!_root) return xml_node();
for (xml_node node = first_child(); node; node = node.next_sibling())
if (pred(node))
return node;
return xml_node();
}
@ -558,7 +641,7 @@ namespace pugi
if (!_root) return xml_node();
xml_node cur = first_child();
while (cur._root && cur._root != _root)
{
if (pred(cur)) return cur;
@ -590,22 +673,22 @@ namespace pugi
// Recursively traverse subtree with xml_tree_walker
bool traverse(xml_tree_walker& walker);
#ifndef PUGIXML_NO_XPATH
// Select single node by evaluating XPath query. Returns first node from the resulting node set.
xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const;
xpath_node select_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
xpath_node select_node(const xpath_query& query) const;
// Select node set by evaluating XPath query
xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
xpath_node_set select_nodes(const xpath_query& query) const;
// (deprecated: use select_node instead) Select single node by evaluating XPath query.
xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const;
xpath_node select_single_node(const xpath_query& query) const;
PUGIXML_DEPRECATED xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL) const;
PUGIXML_DEPRECATED xpath_node select_single_node(const xpath_query& query) const;
#endif
// Print subtree using a writer object
void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
@ -696,13 +779,18 @@ namespace pugi
bool as_bool(bool def = false) const;
// Set text (returns false if object is empty or there is not enough memory)
bool set(const char_t* rhs, size_t sz);
bool set(const char_t* rhs);
// Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
bool set(int rhs);
bool set(unsigned int rhs);
bool set(long rhs);
bool set(unsigned long rhs);
bool set(double rhs);
bool set(double rhs, int precision);
bool set(float rhs);
bool set(float rhs, int precision);
bool set(bool rhs);
#ifdef PUGIXML_HAS_LONG_LONG
@ -714,6 +802,8 @@ namespace pugi
xml_text& operator=(const char_t* rhs);
xml_text& operator=(int rhs);
xml_text& operator=(unsigned int rhs);
xml_text& operator=(long rhs);
xml_text& operator=(unsigned long rhs);
xml_text& operator=(double rhs);
xml_text& operator=(float rhs);
xml_text& operator=(bool rhs);
@ -768,10 +858,10 @@ namespace pugi
xml_node& operator*() const;
xml_node* operator->() const;
const xml_node_iterator& operator++();
xml_node_iterator& operator++();
xml_node_iterator operator++(int);
const xml_node_iterator& operator--();
xml_node_iterator& operator--();
xml_node_iterator operator--(int);
};
@ -810,10 +900,10 @@ namespace pugi
xml_attribute& operator*() const;
xml_attribute* operator->() const;
const xml_attribute_iterator& operator++();
xml_attribute_iterator& operator++();
xml_attribute_iterator operator++(int);
const xml_attribute_iterator& operator--();
xml_attribute_iterator& operator--();
xml_attribute_iterator operator--(int);
};
@ -846,10 +936,10 @@ namespace pugi
xml_node& operator*() const;
xml_node* operator->() const;
const xml_named_node_iterator& operator++();
xml_named_node_iterator& operator++();
xml_named_node_iterator operator++(int);
const xml_named_node_iterator& operator--();
xml_named_node_iterator& operator--();
xml_named_node_iterator operator--(int);
private:
@ -867,11 +957,11 @@ namespace pugi
private:
int _depth;
protected:
// Get current traversal depth
int depth() const;
public:
xml_tree_walker();
virtual ~xml_tree_walker();
@ -942,13 +1032,14 @@ namespace pugi
char_t* _buffer;
char _memory[192];
// Non-copyable semantics
xml_document(const xml_document&);
xml_document& operator=(const xml_document&);
void create();
void destroy();
void _create();
void _destroy();
void _move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
public:
// Default constructor, makes empty document
@ -957,6 +1048,12 @@ namespace pugi
// Destructor, invalidates all node/attribute handles to this document
~xml_document();
#ifdef PUGIXML_HAS_MOVE
// Move semantics support
xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
xml_document& operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT;
#endif
// Removes all nodes, leaving the empty document
void reset();
@ -970,7 +1067,7 @@ namespace pugi
#endif
// (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied.
xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
PUGIXML_DEPRECATED xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
// Load document from zero-terminated string. No encoding conversions are applied.
xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default);
@ -1051,7 +1148,7 @@ namespace pugi
// Non-copyable semantics
xpath_variable(const xpath_variable&);
xpath_variable& operator=(const xpath_variable&);
public:
// Get variable name
const char_t* name() const;
@ -1095,10 +1192,10 @@ namespace pugi
xpath_variable_set(const xpath_variable_set& rhs);
xpath_variable_set& operator=(const xpath_variable_set& rhs);
#if __cplusplus >= 201103
#ifdef PUGIXML_HAS_MOVE
// Move semantics support
xpath_variable_set(xpath_variable_set&& rhs);
xpath_variable_set& operator=(xpath_variable_set&& rhs);
xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT;
xpath_variable_set& operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT;
#endif
// Add a new variable or get the existing one, if the types match
@ -1131,7 +1228,7 @@ namespace pugi
public:
// Construct a compiled object from XPath expression.
// If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors.
explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0);
explicit xpath_query(const char_t* query, xpath_variable_set* variables = PUGIXML_NULL);
// Constructor
xpath_query();
@ -1139,29 +1236,29 @@ namespace pugi
// Destructor
~xpath_query();
#if __cplusplus >= 201103
#ifdef PUGIXML_HAS_MOVE
// Move semantics support
xpath_query(xpath_query&& rhs);
xpath_query& operator=(xpath_query&& rhs);
xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT;
xpath_query& operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT;
#endif
// Get query expression return type
xpath_value_type return_type() const;
// Evaluate expression as boolean value in the specified context; performs type conversion if necessary.
// If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
bool evaluate_boolean(const xpath_node& n) const;
// Evaluate expression as double value in the specified context; performs type conversion if necessary.
// If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
double evaluate_number(const xpath_node& n) const;
#ifndef PUGIXML_NO_STL
// Evaluate expression as string value in the specified context; performs type conversion if necessary.
// If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
string_t evaluate_string(const xpath_node& n) const;
#endif
// Evaluate expression as string value in the specified context; performs type conversion if necessary.
// At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero).
// If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
@ -1188,8 +1285,14 @@ namespace pugi
// Borland C++ workaround
bool operator!() const;
};
#ifndef PUGIXML_NO_EXCEPTIONS
#if defined(_MSC_VER)
// C4275 can be ignored in Visual C++ if you are deriving
// from a type in the Standard C++ Library
#pragma warning(push)
#pragma warning(disable: 4275)
#endif
// XPath exception class
class PUGIXML_CLASS xpath_exception: public std::exception
{
@ -1201,26 +1304,29 @@ namespace pugi
explicit xpath_exception(const xpath_parse_result& result);
// Get error message
virtual const char* what() const throw();
virtual const char* what() const throw() PUGIXML_OVERRIDE;
// Get parse result
const xpath_parse_result& result() const;
};
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#endif
// XPath node class (either xml_node or xml_attribute)
class PUGIXML_CLASS xpath_node
{
private:
xml_node _node;
xml_attribute _attribute;
typedef void (*unspecified_bool_type)(xpath_node***);
public:
// Default constructor; constructs empty XPath node
xpath_node();
// Construct XPath node from XML node/attribute
xpath_node(const xml_node& node);
xpath_node(const xml_attribute& attribute, const xml_node& parent);
@ -1228,13 +1334,13 @@ namespace pugi
// Get node/attribute, if any
xml_node node() const;
xml_attribute attribute() const;
// Get parent of contained node/attribute
xml_node parent() const;
// Safe bool conversion operator
operator unspecified_bool_type() const;
// Borland C++ workaround
bool operator!() const;
@ -1260,13 +1366,13 @@ namespace pugi
type_sorted, // Sorted by document order (ascending)
type_sorted_reverse // Sorted by document order (descending)
};
// Constant iterator type
typedef const xpath_node* const_iterator;
// We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work
typedef const xpath_node* iterator;
// Default constructor. Constructs empty set.
xpath_node_set();
@ -1275,49 +1381,49 @@ namespace pugi
// Destructor
~xpath_node_set();
// Copy constructor/assignment operator
xpath_node_set(const xpath_node_set& ns);
xpath_node_set& operator=(const xpath_node_set& ns);
#if __cplusplus >= 201103
#ifdef PUGIXML_HAS_MOVE
// Move semantics support
xpath_node_set(xpath_node_set&& rhs);
xpath_node_set& operator=(xpath_node_set&& rhs);
xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT;
xpath_node_set& operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT;
#endif
// Get collection type
type_t type() const;
// Get collection size
size_t size() const;
// Indexing operator
const xpath_node& operator[](size_t index) const;
// Collection iterators
const_iterator begin() const;
const_iterator end() const;
// Sort the collection in ascending/descending order by document order
void sort(bool reverse = false);
// Get first node in the collection by document order
xpath_node first() const;
// Check if collection is empty
bool empty() const;
private:
type_t _type;
xpath_node _storage;
xpath_node _storage[1];
xpath_node* _begin;
xpath_node* _end;
void _assign(const_iterator begin, const_iterator end, type_t type);
void _move(xpath_node_set& rhs);
void _move(xpath_node_set& rhs) PUGIXML_NOEXCEPT;
};
#endif
@ -1325,7 +1431,7 @@ namespace pugi
// Convert wide string to UTF8
std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str);
std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str);
// Convert UTF8 to wide string
std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str);
std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >& str);
@ -1333,13 +1439,13 @@ namespace pugi
// Memory allocation function interface; returns pointer to allocated memory or NULL on failure
typedef void* (*allocation_function)(size_t size);
// Memory deallocation function interface
typedef void (*deallocation_function)(void* ptr);
// Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions.
void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
// Get current memory management functions
allocation_function PUGIXML_FUNCTION get_memory_allocation_function();
deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function();
@ -1375,7 +1481,7 @@ namespace std
#endif
/**
* Copyright (c) 2006-2015 Arseny Kapoulkine
* Copyright (c) 2006-2022 Arseny Kapoulkine
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
@ -1388,7 +1494,7 @@ namespace std
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

View file

@ -8,7 +8,11 @@
#if defined(__has_feature)
# define ADDRESS_SANITIZER __has_feature(address_sanitizer)
#else
# define ADDRESS_SANITIZER defined(__SANITIZE_ADDRESS__)
# if defined(__SANITIZE_ADDRESS__)
# define ADDRESS_SANITIZER 1
# else
# define ADDRESS_SANITIZER 0
# endif
#endif
// Low-level allocation functions

View file

@ -1,72 +0,0 @@
#!/usr/bin/perl
use Archive::Tar;
use Archive::Zip;
use File::Basename;
my $target = shift @ARGV;
my @sources = @ARGV;
my $basedir = basename($target, ('.zip', '.tar.gz', '.tgz')) . '/';
my $zip = $target =~ /\.zip$/;
my $arch = $zip ? Archive::Zip->new : Archive::Tar->new;
for $source (sort {$a cmp $b} @sources)
{
my $contents = &readfile_contents($source);
my $meta = &readfile_meta($source);
my $file = $basedir . $source;
if (-T $source)
{
# convert all newlines to Unix format
$contents =~ s/\r//g;
if ($zip)
{
# convert all newlines to Windows format for .zip distribution
$contents =~ s/\n/\r\n/g;
}
}
if ($zip)
{
my $path = $file;
$arch->addDirectory($path) if $path =~ s/\/[^\/]+$/\// && !defined($arch->memberNamed($path));
my $member = $arch->addString($contents, $file);
$member->desiredCompressionMethod(COMPRESSION_DEFLATED);
$member->desiredCompressionLevel(9);
$member->setLastModFileDateTimeFromUnix($$meta{mtime});
}
else
{
$arch->add_data($file, $contents, $meta);
}
}
$zip ? $arch->overwriteAs($target) : $arch->write($target, 9);
sub readfile_contents
{
my $file = shift;
open FILE, $file or die "Can't open $file: $!";
binmode FILE;
my @contents = <FILE>;
close FILE;
return join('', @contents);
}
sub readfile_meta
{
my $file = shift;
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($file);
return {mtime => $mtime};
}

View file

@ -12,13 +12,29 @@ function Invoke-CmdScript($scriptName)
$sources = @("src/pugixml.cpp") + (Get-ChildItem -Path "tests/*.cpp" -Exclude "fuzz_*.cpp")
$failed = $FALSE
foreach ($vs in 9,10,11,12,14)
foreach ($vs in $args)
{
foreach ($arch in "x86","x64")
{
Write-Output "# Setting up VS$vs $arch"
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio $vs.0\VC\vcvarsall.bat" $arch
if ($vs -eq 15) {
$vsdevcmdarch = if ($arch -eq "x64") { "amd64" } else { "x86" }
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" "-arch=$vsdevcmdarch"
}
elseif ($vs -eq 19) {
$vsdevcmdarch = if ($arch -eq "x64") { "amd64" } else { "x86" }
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" "-arch=$vsdevcmdarch"
}
elseif ($vs -eq 22) {
$vsdevcmdarch = if ($arch -eq "x64") { "amd64" } else { "x86" }
Invoke-CmdScript "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" "-arch=$vsdevcmdarch"
}
else
{
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio $vs.0\VC\vcvarsall.bat" $arch
}
if (! $?) { throw "Error setting up VS$vs $arch" }
foreach ($defines in "standard", "PUGIXML_WCHAR_MODE", "PUGIXML_COMPACT")

View file

@ -1,8 +0,0 @@
#ifndef HEADER_TEST_COMMON_HPP
#define HEADER_TEST_COMMON_HPP
#include "test.hpp"
using namespace pugi;
#endif

View file

@ -0,0 +1 @@
a/b/c

View file

@ -0,0 +1 @@
sum(nodes) + round(concat(//a[translate(@id, 'abc', '012')]))

View file

@ -0,0 +1 @@
1+2*3 div 4 mod 5-6

View file

@ -0,0 +1 @@
@*/ancestor::*/near-north/*[4]/@*/preceding::text()

View file

@ -0,0 +1 @@
library/nodes[@id=12]/element[@type='translate'][1]

View file

@ -1,16 +1,14 @@
#include "../src/pugixml.hpp"
#include "allocator.hpp"
int main(int argc, const char** argv)
#include <stdint.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
pugi::set_memory_management_functions(memory_allocate, memory_deallocate);
pugi::xml_document doc;
for (int i = 1; i < argc; ++i)
{
doc.load_file(argv[i]);
doc.load_file(argv[i], pugi::parse_minimal);
doc.load_file(argv[i], pugi::parse_full);
}
doc.load_buffer(Data, Size);
doc.load_buffer(Data, Size, pugi::parse_minimal);
doc.load_buffer(Data, Size, pugi::parse_full);
return 0;
}

72
tests/fuzz_parse.dict Normal file
View file

@ -0,0 +1,72 @@
#
# AFL dictionary for XML
# ----------------------
#
# Several basic syntax elements and attributes, modeled on libxml2.
#
# Created by Michal Zalewski <lcamtuf@google.com>
#
attr_encoding=" encoding=\"1\""
attr_generic=" a=\"1\""
attr_href=" href=\"1\""
attr_standalone=" standalone=\"no\""
attr_version=" version=\"1\""
attr_xml_base=" xml:base=\"1\""
attr_xml_id=" xml:id=\"1\""
attr_xml_lang=" xml:lang=\"1\""
attr_xml_space=" xml:space=\"1\""
attr_xmlns=" xmlns=\"1\""
entity_builtin="&lt;"
entity_decimal="&#1;"
entity_external="&a;"
entity_hex="&#x1;"
string_any="ANY"
string_brackets="[]"
string_cdata="CDATA"
string_col_fallback=":fallback"
string_col_generic=":a"
string_col_include=":include"
string_dashes="--"
string_empty="EMPTY"
string_empty_dblquotes="\"\""
string_empty_quotes="''"
string_entities="ENTITIES"
string_entity="ENTITY"
string_fixed="#FIXED"
string_id="ID"
string_idref="IDREF"
string_idrefs="IDREFS"
string_implied="#IMPLIED"
string_nmtoken="NMTOKEN"
string_nmtokens="NMTOKENS"
string_notation="NOTATION"
string_parentheses="()"
string_pcdata="#PCDATA"
string_percent="%a"
string_public="PUBLIC"
string_required="#REQUIRED"
string_schema=":schema"
string_system="SYSTEM"
string_ucs4="UCS-4"
string_utf16="UTF-16"
string_utf8="UTF-8"
string_xmlns="xmlns:"
tag_attlist="<!ATTLIST"
tag_cdata="<![CDATA["
tag_close="</a>"
tag_doctype="<!DOCTYPE"
tag_element="<!ELEMENT"
tag_entity="<!ENTITY"
tag_ignore="<![IGNORE["
tag_include="<![INCLUDE["
tag_notation="<!NOTATION"
tag_open="<a>"
tag_open_close="<a />"
tag_open_exclamation="<!"
tag_open_q="<?"
tag_sq2_close="]]>"
tag_xml_q="<?xml?>"

11
tests/fuzz_setup.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
sudo apt-get --yes install subversion screen gcc g++ cmake ninja-build golang autoconf libtool apache2 python-dev pkg-config zlib1g-dev libgcrypt11-dev
mkdir -p clang
cd clang
git clone https://chromium.googlesource.com/chromium/src/tools/clang
cd ..
clang/clang/scripts/update.py
sudo cp -rf third_party/llvm-build/Release+Asserts/lib/* /usr/local/lib/
sudo cp -rf third_party/llvm-build/Release+Asserts/bin/* /usr/local/bin

26
tests/fuzz_xpath.cpp Normal file
View file

@ -0,0 +1,26 @@
#include "../src/pugixml.hpp"
#include <stdint.h>
#include <string.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
char* text = new char[Size + 1];
memcpy(text, Data, Size);
text[Size] = 0;
#ifdef PUGIXML_NO_EXCEPTIONS
pugi::xpath_query q(text);
#else
try
{
pugi::xpath_query q(text);
}
catch (pugi::xpath_exception&)
{
}
#endif
delete[] text;
return 0;
}

72
tests/fuzz_xpath.dict Normal file
View file

@ -0,0 +1,72 @@
"boolean"
"count"
"contains"
"concat"
"ceiling"
"false"
"floor"
"id"
"last"
"lang"
"local-name"
"name"
"namespace-uri"
"normalize-space"
"not"
"number"
"position"
"round"
"string"
"string-length"
"starts-with"
"substring-before"
"substring-after"
"substring"
"sum"
"translate"
"true"
"ancestor"
"ancestor-or-self"
"attribute"
"child"
"descendant"
"descendant-or-self"
"following"
"following-sibling"
"namespace"
"parent"
"preceding"
"preceding-sibling"
"self"
"comment"
"node"
"processing-instruction"
"text"
"or"
"and"
"div"
"mod"
">"
">="
"<"
"<="
"!"
"!="
"="
"+"
"-"
"*"
"|"
"$"
"("
")"
"["
"]"
","
"//"
"/"
".."
"."
"@"
"::"
":"

View file

@ -1,7 +1,7 @@
#ifndef HEADER_TEST_HELPERS_HPP
#define HEADER_TEST_HELPERS_HPP
#include "common.hpp"
#include "test.hpp"
#include <utility>

View file

@ -41,11 +41,11 @@ static void* custom_allocate(size_t size)
else
{
void* ptr = memory_allocate(size);
assert(ptr);
if (!ptr) return 0;
g_memory_total_size += memory_size(ptr);
g_memory_total_count++;
return ptr;
}
}
@ -68,7 +68,7 @@ static void custom_deallocate(void* ptr)
g_memory_total_size -= memory_size(ptr);
g_memory_total_count--;
memory_deallocate(ptr);
}
@ -105,9 +105,9 @@ static bool run_test(test_runner* test, const char* test_name, pugi::allocation_
g_memory_fail_triggered = false;
test_runner::_memory_fail_threshold = 0;
test_runner::_memory_fail_triggered = false;
pugi::set_memory_management_functions(allocate, custom_deallocate);
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4611) // interaction between _setjmp and C++ object destruction is non-portable
@ -115,7 +115,7 @@ static bool run_test(test_runner* test, const char* test_name, pugi::allocation_
#endif
volatile int result = setjmp(test_runner::_failure_buffer);
#ifdef _MSC_VER
# pragma warning(pop)
#endif
@ -177,7 +177,7 @@ int main(int, char** argv)
temp.erase((slash != std::string::npos) ? slash + 1 : 0);
test_runner::_temp_path = temp.c_str();
replace_memory_management();
unsigned int total = 0;
@ -190,13 +190,14 @@ int main(int, char** argv)
total++;
passed += run_test(test, test->_name, custom_allocate);
#ifndef PUGIXML_NO_EXCEPTIONS
if (g_memory_fail_triggered)
{
// run tests that trigger memory failures twice - with an allocator that returns NULL and with an allocator that throws
#ifndef PUGIXML_NO_EXCEPTIONS
total++;
passed += run_test(test, (test->_name + std::string(" (throw)")).c_str(), custom_allocate_throw);
#endif
}
#endif
}
unsigned int failed = total - passed;

View file

@ -117,7 +117,7 @@ bool test_xpath_number(const pugi::xpath_node& node, const pugi::char_t* query,
double value = q.evaluate_number(node);
double absolute_error = fabs(value - expected);
const double tolerance = 1e-15f;
const double tolerance = 1e-15;
return absolute_error < tolerance || absolute_error < fabs(expected) * tolerance;
}

View file

@ -5,6 +5,10 @@
#include <setjmp.h>
#ifndef PUGIXML_NO_EXCEPTIONS
#include <new>
#endif
struct test_runner
{
test_runner(const char* name)
@ -78,7 +82,7 @@ struct dummy_fixture {};
{ \
test_runner_##name(): test_runner(#name) {} \
\
virtual void run() \
virtual void run() PUGIXML_OVERRIDE \
{ \
test_runner_helper_##name helper; \
helper.run(); \
@ -112,8 +116,8 @@ struct dummy_fixture {};
#define CHECK_TEXT(condition, text) if (condition) ; else test_runner::_failure_message = CHECK_JOIN2(text, __FILE__, __LINE__), longjmp(test_runner::_failure_buffer, 1)
#define CHECK_FORCE_FAIL(text) test_runner::_failure_message = CHECK_JOIN2(text, __FILE__, __LINE__), longjmp(test_runner::_failure_buffer, 1)
#if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(__MWERKS__)
# define STRINGIZE(value) "??" // MSVC 6.0 and CodeWarrior have troubles stringizing stuff with strings w/escaping inside
#if (defined(_MSC_VER) && _MSC_VER == 1200) || defined(__MWERKS__) || (defined(__BORLANDC__) && __BORLANDC__ <= 0x540)
# define STRINGIZE(value) "??" // Some compilers have issues with stringizing expressions that contain strings w/escaping inside
#else
# define STRINGIZE(value) #value
#endif
@ -150,14 +154,14 @@ struct dummy_fixture {};
#define STR(text) PUGIXML_TEXT(text)
#ifdef __DMC__
#if defined(__DMC__) || defined(__BORLANDC__)
#define U_LITERALS // DMC does not understand \x01234 (it parses first three digits), but understands \u01234
#endif
#if (defined(_MSC_VER) && _MSC_VER == 1200) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER == 800) || defined(__BORLANDC__)
// NaN comparison on MSVC6 is incorrect, see http://www.nabble.com/assertDoubleEquals,-NaN---Microsoft-Visual-Studio-6-td9137859.html
// IC8 and BCC are also affected by the same bug
# define MSVC6_NAN_BUG
# define MSVC6_NAN_BUG
#endif
inline wchar_t wchar_cast(unsigned int value)

150
tests/test_compact.cpp Normal file
View file

@ -0,0 +1,150 @@
#ifdef PUGIXML_COMPACT
#include "test.hpp"
using namespace pugi;
static void overflow_hash_table(xml_document& doc)
{
xml_node n = doc.child(STR("n"));
// compact encoding assumes next_sibling is a forward-only pointer so we can allocate hash entries by reordering nodes
// we allocate enough hash entries to be exactly on the edge of rehash threshold
for (int i = 0; i < 8; ++i)
CHECK(n.prepend_child(node_element));
}
TEST_XML_FLAGS(compact_out_of_memory_string, "<n a='v'/><?n v?>", parse_pi)
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_attribute a = doc.child(STR("n")).attribute(STR("a"));
xml_node pi = doc.last_child();
CHECK_ALLOC_FAIL(CHECK(!pi.set_name(STR("name"))));
CHECK_ALLOC_FAIL(CHECK(!pi.set_value(STR("value"))));
CHECK_ALLOC_FAIL(CHECK(!a.set_name(STR("name"))));
CHECK_ALLOC_FAIL(CHECK(!a.set_value(STR("value"))));
}
TEST_XML(compact_out_of_memory_attribute, "<n a='v'/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
xml_attribute a = n.attribute(STR("a"));
CHECK_ALLOC_FAIL(CHECK(!n.append_attribute(STR(""))));
CHECK_ALLOC_FAIL(CHECK(!n.prepend_attribute(STR(""))));
CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_after(STR(""), a)));
CHECK_ALLOC_FAIL(CHECK(!n.insert_attribute_before(STR(""), a)));
}
TEST_XML(compact_out_of_memory_attribute_copy, "<n a='v'/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
xml_attribute a = n.attribute(STR("a"));
CHECK_ALLOC_FAIL(CHECK(!n.append_copy(a)));
CHECK_ALLOC_FAIL(CHECK(!n.prepend_copy(a)));
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_after(a, a)));
CHECK_ALLOC_FAIL(CHECK(!n.insert_copy_before(a, a)));
}
TEST_XML(compact_out_of_memory_node, "<n/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
CHECK_ALLOC_FAIL(CHECK(!doc.append_child(node_element)));
CHECK_ALLOC_FAIL(CHECK(!doc.prepend_child(node_element)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_child_after(node_element, n)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_child_before(node_element, n)));
}
TEST_XML(compact_out_of_memory_node_copy, "<n/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
CHECK_ALLOC_FAIL(CHECK(!doc.append_copy(n)));
CHECK_ALLOC_FAIL(CHECK(!doc.prepend_copy(n)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_copy_after(n, n)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_copy_before(n, n)));
}
TEST_XML(compact_out_of_memory_node_move, "<n/><ne/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
xml_node ne = doc.child(STR("ne"));
CHECK_ALLOC_FAIL(CHECK(!doc.append_move(n)));
CHECK_ALLOC_FAIL(CHECK(!doc.prepend_move(n)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_move_after(n, ne)));
CHECK_ALLOC_FAIL(CHECK(!doc.insert_move_before(n, ne)));
}
TEST_XML(compact_out_of_memory_remove, "<n a='v'/>")
{
test_runner::_memory_fail_threshold = 1;
overflow_hash_table(doc);
xml_node n = doc.child(STR("n"));
xml_attribute a = n.attribute(STR("a"));
CHECK_ALLOC_FAIL(CHECK(!n.remove_attribute(a)));
CHECK_ALLOC_FAIL(CHECK(!doc.remove_child(n)));
}
TEST_XML(compact_pointer_attribute_list, "<n a='v'/>")
{
xml_node n = doc.child(STR("n"));
xml_attribute a = n.attribute(STR("a"));
// make sure we fill the page with node x
for (int i = 0; i < 1000; ++i)
doc.append_child(STR("x"));
// this requires extended encoding for prev_attribute_c/next_attribute
n.append_attribute(STR("b"));
// this requires extended encoding for first_attribute
n.remove_attribute(a);
CHECK(!n.attribute(STR("a")));
CHECK(n.attribute(STR("b")));
}
TEST_XML(compact_pointer_node_list, "<n/>")
{
xml_node n = doc.child(STR("n"));
// make sure we fill the page with node x
// this requires extended encoding for prev_sibling_c/next_sibling
for (int i = 0; i < 1000; ++i)
doc.append_child(STR("x"));
// this requires extended encoding for first_child
n.append_child(STR("child"));
CHECK(n.child(STR("child")));
}
#endif

25
tests/test_deprecated.cpp Normal file
View file

@ -0,0 +1,25 @@
#define PUGIXML_DEPRECATED // Suppress deprecated declarations to avoid warnings
#include "test.hpp"
using namespace pugi;
TEST(document_deprecated_load)
{
xml_document doc;
CHECK(doc.load(STR("<node/>")));
CHECK_NODE(doc, STR("<node/>"));
}
#ifndef PUGIXML_NO_XPATH
TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><foo/><tail/></node>")
{
xpath_node n1 = doc.select_single_node(STR("node/foo"));
xpath_query q(STR("node/foo"));
xpath_node n2 = doc.select_single_node(q);
CHECK(n1.node().attribute(STR("id")).as_int() == 1);
CHECK(n2.node().attribute(STR("id")).as_int() == 1);
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,11 @@
#include "common.hpp"
#include "test.hpp"
#include "helpers.hpp"
#include <limits.h>
using namespace pugi;
TEST_XML_FLAGS(dom_text_empty, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
{
xml_node node = doc.child(STR("node"));
@ -120,12 +124,12 @@ TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</
xml_node node = doc.child(STR("node"));
CHECK(xml_text().as_float() == 0);
CHECK_DOUBLE(node.child(STR("text1")).text().as_float(), 0);
CHECK_DOUBLE(node.child(STR("text2")).text().as_float(), 1);
CHECK_DOUBLE(node.child(STR("text3")).text().as_float(), 0.12);
CHECK_DOUBLE(node.child(STR("text4")).text().as_float(), -5.1);
CHECK_DOUBLE(node.child(STR("text5")).text().as_float(), 3e-4);
CHECK_DOUBLE(node.child(STR("text6")).text().as_float(), 3.14159265358979323846);
CHECK_DOUBLE(double(node.child(STR("text1")).text().as_float()), 0);
CHECK_DOUBLE(double(node.child(STR("text2")).text().as_float()), 1);
CHECK_DOUBLE(double(node.child(STR("text3")).text().as_float()), 0.12);
CHECK_DOUBLE(double(node.child(STR("text4")).text().as_float()), -5.1);
CHECK_DOUBLE(double(node.child(STR("text5")).text().as_float()), 3e-4);
CHECK_DOUBLE(double(node.child(STR("text6")).text().as_float()), 3.14159265358979323846);
}
TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
@ -245,6 +249,46 @@ TEST_XML(dom_text_set, "<node/>")
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
}
TEST_XML(dom_text_set_with_size, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
t.set(STR(""), 0);
CHECK(node.first_child().type() == node_pcdata);
CHECK_NODE(node, STR("<node></node>"));
t.set(STR("boo"), 3);
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>boo</node>"));
t.set(STR("foobarfoobar"), 12);
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
}
TEST_XML(dom_text_set_partially_with_size, "<node/>")
{
xml_node node = doc.child(STR("node"));
xml_text t = node.text();
t.set(STR("foo"), 0);
CHECK(node.first_child().type() == node_pcdata);
CHECK_NODE(node, STR("<node></node>"));
t.set(STR("boofoo"), 3);
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>boo</node>"));
t.set(STR("foobarfoobar"), 3);
CHECK(node.first_child().type() == node_pcdata);
CHECK(node.first_child() == node.last_child());
CHECK_NODE(node, STR("<node>foo</node>"));
}
TEST_XML(dom_text_assign, "<node/>")
{
xml_node node = doc.child(STR("node"));
@ -299,11 +343,73 @@ TEST_XML(dom_text_set_value, "<node/>")
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
}
#if LONG_MAX > 2147483647
TEST_XML(dom_text_assign_long, "<node/>")
{
xml_node node = doc.child(STR("node"));
node.append_child(STR("text1")).text() = -9223372036854775807l;
node.append_child(STR("text2")).text() = -9223372036854775807l - 1;
xml_text() = -9223372036854775807l - 1;
node.append_child(STR("text3")).text() = 18446744073709551615ul;
node.append_child(STR("text4")).text() = 18446744073709551614ul;
xml_text() = 18446744073709551615ul;
CHECK_NODE(node, STR("<node><text1>-9223372036854775807</text1><text2>-9223372036854775808</text2><text3>18446744073709551615</text3><text4>18446744073709551614</text4></node>"));
}
TEST_XML(dom_text_set_value_long, "<node/>")
{
xml_node node = doc.child(STR("node"));
CHECK(node.append_child(STR("text1")).text().set(-9223372036854775807l));
CHECK(node.append_child(STR("text2")).text().set(-9223372036854775807l - 1));
CHECK(!xml_text().set(-9223372036854775807l - 1));
CHECK(node.append_child(STR("text3")).text().set(18446744073709551615ul));
CHECK(node.append_child(STR("text4")).text().set(18446744073709551614ul));
CHECK(!xml_text().set(18446744073709551615ul));
CHECK_NODE(node, STR("<node><text1>-9223372036854775807</text1><text2>-9223372036854775808</text2><text3>18446744073709551615</text3><text4>18446744073709551614</text4></node>"));
}
#else
TEST_XML(dom_text_assign_long, "<node/>")
{
xml_node node = doc.child(STR("node"));
node.append_child(STR("text1")).text() = -2147483647l;
node.append_child(STR("text2")).text() = -2147483647l - 1;
xml_text() = -2147483647l - 1;
node.append_child(STR("text3")).text() = 4294967295ul;
node.append_child(STR("text4")).text() = 4294967294ul;
xml_text() = 4294967295ul;
CHECK_NODE(node, STR("<node><text1>-2147483647</text1><text2>-2147483648</text2><text3>4294967295</text3><text4>4294967294</text4></node>"));
}
TEST_XML(dom_text_set_value_long, "<node/>")
{
xml_node node = doc.child(STR("node"));
CHECK(node.append_child(STR("text1")).text().set(-2147483647l));
CHECK(node.append_child(STR("text2")).text().set(-2147483647l - 1));
CHECK(!xml_text().set(-2147483647l - 1));
CHECK(node.append_child(STR("text3")).text().set(4294967295ul));
CHECK(node.append_child(STR("text4")).text().set(4294967294ul));
CHECK(!xml_text().set(4294967295ul));
CHECK_NODE(node, STR("<node><text1>-2147483647</text1><text2>-2147483648</text2><text3>4294967295</text3><text4>4294967294</text4></node>"));
}
#endif
#ifdef PUGIXML_HAS_LONG_LONG
TEST_XML(dom_text_assign_llong, "<node/>")
{
xml_node node = doc.child(STR("node"));
node.append_child(STR("text1")).text() = -9223372036854775807ll;
node.append_child(STR("text2")).text() = -9223372036854775807ll - 1;
xml_text() = -9223372036854775807ll - 1;
@ -311,14 +417,14 @@ TEST_XML(dom_text_assign_llong, "<node/>")
node.append_child(STR("text3")).text() = 18446744073709551615ull;
node.append_child(STR("text4")).text() = 18446744073709551614ull;
xml_text() = 18446744073709551615ull;
CHECK_NODE(node, STR("<node><text1>-9223372036854775807</text1><text2>-9223372036854775808</text2><text3>18446744073709551615</text3><text4>18446744073709551614</text4></node>"));
}
TEST_XML(dom_text_set_value_llong, "<node/>")
{
xml_node node = doc.child(STR("node"));
CHECK(node.append_child(STR("text1")).text().set(-9223372036854775807ll));
CHECK(node.append_child(STR("text2")).text().set(-9223372036854775807ll - 1));
CHECK(!xml_text().set(-9223372036854775807ll - 1));
@ -339,16 +445,16 @@ TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
CHECK_STRING(t.get(), STR("text"));
t.set(STR("notext"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2 /></node>"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2/></node>"));
CHECK(node.remove_child(t.data()));
CHECK(!t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 /></node>"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/></node>"));
t.set(STR("yestext"));
CHECK(t);
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2 />yestext</node>"));
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/>yestext</node>"));
CHECK(t.data() == node.last_child());
}

View file

@ -2,7 +2,7 @@
#define _SCL_SECURE_NO_WARNINGS
#define _SCL_SECURE_NO_DEPRECATE
#include "common.hpp"
#include "test.hpp"
#include <string.h>
#include <stdio.h>
@ -15,6 +15,8 @@
#include "helpers.hpp"
using namespace pugi;
#ifdef PUGIXML_NO_STL
template <typename I> static I move_iter(I base, int n)
{
@ -57,10 +59,10 @@ TEST_XML(dom_attr_next_previous_attribute, "<node attr1='1' attr2='2' />")
CHECK(attr1.next_attribute() == attr2);
CHECK(attr2.next_attribute() == xml_attribute());
CHECK(attr1.previous_attribute() == xml_attribute());
CHECK(attr2.previous_attribute() == attr1);
CHECK(xml_attribute().next_attribute() == xml_attribute());
CHECK(xml_attribute().previous_attribute() == xml_attribute());
}
@ -137,6 +139,10 @@ TEST_XML(dom_attr_as_integer_space, "<node attr1=' \t1234' attr2='\t 0x123' attr
CHECK(node.attribute(STR("attr2")).as_int() == 291);
CHECK(node.attribute(STR("attr3")).as_int() == 0);
CHECK(node.attribute(STR("attr4")).as_int() == 0);
#ifdef PUGIXML_HAS_LONG_LONG
CHECK(node.attribute(STR("attr1")).as_llong() == 1234);
#endif
}
TEST_XML(dom_attr_as_float, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
@ -144,12 +150,12 @@ TEST_XML(dom_attr_as_float, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1'
xml_node node = doc.child(STR("node"));
CHECK(xml_attribute().as_float() == 0);
CHECK_DOUBLE(node.attribute(STR("attr1")).as_float(), 0);
CHECK_DOUBLE(node.attribute(STR("attr2")).as_float(), 1);
CHECK_DOUBLE(node.attribute(STR("attr3")).as_float(), 0.12);
CHECK_DOUBLE(node.attribute(STR("attr4")).as_float(), -5.1);
CHECK_DOUBLE(node.attribute(STR("attr5")).as_float(), 3e-4);
CHECK_DOUBLE(node.attribute(STR("attr6")).as_float(), 3.14159265358979323846);
CHECK_DOUBLE(double(node.attribute(STR("attr1")).as_float()), 0);
CHECK_DOUBLE(double(node.attribute(STR("attr2")).as_float()), 1);
CHECK_DOUBLE(double(node.attribute(STR("attr3")).as_float()), 0.12);
CHECK_DOUBLE(double(node.attribute(STR("attr4")).as_float()), -5.1);
CHECK_DOUBLE(double(node.attribute(STR("attr5")).as_float()), 3e-4);
CHECK_DOUBLE(double(node.attribute(STR("attr6")).as_float()), 3.14159265358979323846);
}
TEST_XML(dom_attr_as_double, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
@ -333,11 +339,11 @@ TEST_XML(dom_attr_iterator_invalidate, "<node><node1 attr1='0'/><node2 attr1='0'
TEST_XML(dom_attr_iterator_const, "<node attr1='0' attr2='1'/>")
{
pugi::xml_node node = doc.child(STR("node"));
xml_node node = doc.child(STR("node"));
const pugi::xml_attribute_iterator i1 = node.attributes_begin();
const pugi::xml_attribute_iterator i2 = ++xml_attribute_iterator(i1);
const pugi::xml_attribute_iterator i3 = ++xml_attribute_iterator(i2);
const xml_attribute_iterator i1 = node.attributes_begin();
const xml_attribute_iterator i2 = ++xml_attribute_iterator(i1);
const xml_attribute_iterator i3 = ++xml_attribute_iterator(i2);
CHECK(*i1 == node.attribute(STR("attr1")));
CHECK(*i2 == node.attribute(STR("attr2")));
@ -455,11 +461,11 @@ TEST_XML(dom_node_iterator_invalidate, "<node><node1><child1/></node1><node2><ch
TEST_XML(dom_node_iterator_const, "<node><child1/><child2/></node>")
{
pugi::xml_node node = doc.child(STR("node"));
xml_node node = doc.child(STR("node"));
const pugi::xml_node_iterator i1 = node.begin();
const pugi::xml_node_iterator i2 = ++xml_node_iterator(i1);
const pugi::xml_node_iterator i3 = ++xml_node_iterator(i2);
const xml_node_iterator i1 = node.begin();
const xml_node_iterator i2 = ++xml_node_iterator(i1);
const xml_node_iterator i3 = ++xml_node_iterator(i2);
CHECK(*i1 == node.child(STR("child1")));
CHECK(*i2 == node.child(STR("child2")));
@ -497,7 +503,7 @@ TEST_XML_FLAGS(dom_node_type, "<?xml?><!DOCTYPE><?pi?><!--comment--><node>pcdata
CHECK((it++)->type() == node_element);
xml_node_iterator cit = doc.child(STR("node")).begin();
CHECK((cit++)->type() == node_pcdata);
CHECK((cit++)->type() == node_cdata);
}
@ -516,7 +522,7 @@ TEST_XML_FLAGS(dom_node_name_value, "<?xml?><!DOCTYPE id><?pi?><!--comment--><no
CHECK_NAME_VALUE(*it++, STR("node"), STR(""));
xml_node_iterator cit = doc.child(STR("node")).begin();
CHECK_NAME_VALUE(*cit++, STR(""), STR("pcdata"));
CHECK_NAME_VALUE(*cit++, STR(""), STR("cdata"));
}
@ -555,10 +561,10 @@ TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></nod
CHECK(child1.next_sibling() == child2);
CHECK(child3.next_sibling() == xml_node());
CHECK(child1.previous_sibling() == xml_node());
CHECK(child3.previous_sibling() == child2);
CHECK(child1.next_sibling(STR("child3")) == child3);
CHECK(child1.next_sibling(STR("child")) == xml_node());
@ -665,9 +671,9 @@ struct find_predicate_const
struct find_predicate_prefix
{
const pugi::char_t* prefix;
const char_t* prefix;
find_predicate_prefix(const pugi::char_t* prefix_): prefix(prefix_)
find_predicate_prefix(const char_t* prefix_): prefix(prefix_)
{
}
@ -675,7 +681,7 @@ struct find_predicate_prefix
{
#ifdef PUGIXML_WCHAR_MODE
// can't use wcsncmp here because of a bug in DMC
return std::basic_string<pugi::char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
return std::basic_string<char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
#else
return strncmp(obj.name(), prefix, strlen(prefix)) == 0;
#endif
@ -728,14 +734,17 @@ TEST_XML(dom_node_find_node, "<node><child1/><child2/></node>")
TEST_XML(dom_node_path, "<node><child1>text<child2/></child1></node>")
{
CHECK(xml_node().path() == STR(""));
CHECK(doc.path() == STR(""));
CHECK(doc.child(STR("node")).path() == STR("/node"));
CHECK(doc.child(STR("node")).child(STR("child1")).path() == STR("/node/child1"));
CHECK(doc.child(STR("node")).child(STR("child1")).child(STR("child2")).path() == STR("/node/child1/child2"));
CHECK(doc.child(STR("node")).child(STR("child1")).first_child().path() == STR("/node/child1/"));
CHECK(doc.child(STR("node")).child(STR("child1")).path('\\') == STR("\\node\\child1"));
doc.append_child(node_element);
CHECK(doc.last_child().path() == STR("/"));
}
#endif
@ -743,7 +752,7 @@ TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></
{
CHECK(xml_node().first_element_by_path(STR("/")) == xml_node());
CHECK(xml_node().first_element_by_path(STR("a")) == xml_node());
CHECK(doc.first_element_by_path(STR("")) == doc);
CHECK(doc.first_element_by_path(STR("/")) == doc);
@ -757,7 +766,7 @@ TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></
#endif
CHECK(doc.first_element_by_path(STR("/node/child2")) == xml_node());
CHECK(doc.first_element_by_path(STR("\\node\\child1"), '\\') == doc.child(STR("node")).child(STR("child1")));
CHECK(doc.child(STR("node")).first_element_by_path(STR("..")) == doc);
@ -775,7 +784,7 @@ TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></
struct test_walker: xml_tree_walker
{
std::basic_string<pugi::char_t> log;
std::basic_string<char_t> log;
unsigned int call_count;
unsigned int stop_count;
@ -783,22 +792,27 @@ struct test_walker: xml_tree_walker
{
}
std::basic_string<pugi::char_t> depthstr() const
std::basic_string<char_t> depthstr() const
{
char buf[32];
#if __cplusplus >= 201103 || defined(__APPLE__) // Xcode 14 warns about use of sprintf in C++98 builds
snprintf(buf, sizeof(buf), "%d", depth());
#else
sprintf(buf, "%d", depth());
#endif
#ifdef PUGIXML_WCHAR_MODE
wchar_t wbuf[32];
std::copy(buf, buf + strlen(buf) + 1, &wbuf[0]);
return std::basic_string<pugi::char_t>(wbuf);
return std::basic_string<char_t>(wbuf);
#else
return std::basic_string<pugi::char_t>(buf);
return std::basic_string<char_t>(buf);
#endif
}
virtual bool begin(xml_node& node)
virtual bool begin(xml_node& node) PUGIXML_OVERRIDE
{
log += STR("|");
log += depthstr();
@ -810,7 +824,7 @@ struct test_walker: xml_tree_walker
return ++call_count != stop_count && xml_tree_walker::begin(node);
}
virtual bool for_each(xml_node& node)
virtual bool for_each(xml_node& node) PUGIXML_OVERRIDE
{
log += STR("|");
log += depthstr();
@ -822,7 +836,7 @@ struct test_walker: xml_tree_walker
return ++call_count != stop_count && xml_tree_walker::end(node);
}
virtual bool end(xml_node& node)
virtual bool end(xml_node& node) PUGIXML_OVERRIDE
{
log += STR("|");
log += depthstr();
@ -919,7 +933,7 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><!DOCTYPE><?pi?><!--comment--><node>pcd
CHECK((it++)->offset_debug() == 38);
xml_node_iterator cit = doc.child(STR("node")).begin();
CHECK((cit++)->offset_debug() == 43);
CHECK((cit++)->offset_debug() == 58);
}
@ -966,7 +980,7 @@ TEST_XML(dom_internal_object, "<node attr='value'>value</node>")
xml_node node = doc.child(STR("node"));
xml_attribute attr = node.first_attribute();
xml_node value = node.first_child();
CHECK(xml_node().internal_object() == 0);
CHECK(xml_attribute().internal_object() == 0);
@ -988,7 +1002,7 @@ TEST_XML(dom_hash_value, "<node attr='value'>value</node>")
xml_node node = doc.child(STR("node"));
xml_attribute attr = node.first_attribute();
xml_node value = node.first_child();
CHECK(xml_node().hash_value() == 0);
CHECK(xml_attribute().hash_value() == 0);
@ -1274,3 +1288,17 @@ TEST_XML(dom_as_int_plus, "<node attr1='+1' attr2='+0xa' />")
CHECK(node.attribute(STR("attr2")).as_ullong() == 10);
#endif
}
TEST(dom_node_anonymous)
{
xml_document doc;
doc.append_child(node_element);
doc.append_child(node_element);
doc.append_child(node_pcdata);
CHECK(doc.child(STR("node")) == xml_node());
CHECK(doc.first_child().next_sibling(STR("node")) == xml_node());
CHECK(doc.last_child().previous_sibling(STR("node")) == xml_node());
CHECK_STRING(doc.child_value(), STR(""));
CHECK_STRING(doc.last_child().child_value(), STR(""));
}

View file

@ -1,12 +1,14 @@
#define PUGIXML_HEADER_ONLY
#define pugi pugih
#include "common.hpp"
#include "test.hpp"
// Check header guards
#include "../src/pugixml.hpp"
#include "../src/pugixml.hpp"
using namespace pugi;
TEST(header_only_1)
{
xml_document doc;

View file

@ -1,12 +1,14 @@
#define PUGIXML_HEADER_ONLY
#define pugi pugih
#include "common.hpp"
#include "test.hpp"
// Check header guards
#include "../src/pugixml.hpp"
#include "../src/pugixml.hpp"
using namespace pugi;
TEST(header_only_2)
{
xml_document doc;

View file

@ -1,4 +1,4 @@
#include "common.hpp"
#include "test.hpp"
#include "writer_string.hpp"
#include "allocator.hpp"
@ -6,6 +6,8 @@
#include <string>
#include <vector>
using namespace pugi;
namespace
{
int page_allocs = 0;
@ -48,7 +50,7 @@ TEST(memory_custom_memory_management)
CHECK(page_allocs == 0 && page_deallocs == 0);
CHECK(doc.load_string(STR("<node />")));
CHECK(page_allocs == 1 && page_deallocs == 0);
// modify document (no new page)
@ -56,7 +58,7 @@ TEST(memory_custom_memory_management)
CHECK(page_allocs == 1 && page_deallocs == 0);
// modify document (new page)
std::basic_string<pugi::char_t> s(65536, 'x');
std::basic_string<char_t> s(65536, 'x');
CHECK(doc.first_child().set_name(s.c_str()));
CHECK(page_allocs == 2 && page_deallocs == 0);
@ -93,7 +95,7 @@ TEST(memory_large_allocations)
// initial fill
for (size_t i = 0; i < 128; ++i)
{
std::basic_string<pugi::char_t> s(i * 128, 'x');
std::basic_string<char_t> s(i * 128, 'x');
CHECK(doc.append_child(node_pcdata).set_value(s.c_str()));
}
@ -103,12 +105,12 @@ TEST(memory_large_allocations)
// grow-prune loop
while (doc.first_child())
{
pugi::xml_node node;
xml_node node;
// grow
for (node = doc.first_child(); node; node = node.next_sibling())
{
std::basic_string<pugi::char_t> s = node.value();
std::basic_string<char_t> s = node.value();
CHECK(node.set_value((s + s).c_str()));
}
@ -116,7 +118,7 @@ TEST(memory_large_allocations)
// prune
for (node = doc.first_child(); node; )
{
pugi::xml_node next = node.next_sibling().next_sibling();
xml_node next = node.next_sibling().next_sibling();
node.parent().remove_child(node);
@ -159,7 +161,7 @@ TEST(memory_page_management)
for (size_t i = 0; i < 4000; ++i)
{
xml_node node = doc.append_child(STR("node"));
xml_node node = doc.append_child(STR("n"));
CHECK(node);
nodes.push_back(node);

View file

@ -1,7 +1,9 @@
#include "common.hpp"
#include "test.hpp"
#include "writer_string.hpp"
using namespace pugi;
TEST(parse_pi_skip)
{
xml_document doc;
@ -82,12 +84,22 @@ TEST(parse_pi_error)
CHECK(doc.load_string(STR("<?name&"), flags).status == status_bad_pi);
CHECK(doc.load_string(STR("<?name&?"), flags).status == status_bad_pi);
}
CHECK(doc.load_string(STR("<?xx#?>"), parse_fragment | parse_pi).status == status_bad_pi);
CHECK(doc.load_string(STR("<?name&?>"), parse_fragment | parse_pi).status == status_bad_pi);
CHECK(doc.load_string(STR("<?name& x?>"), parse_fragment | parse_pi).status == status_bad_pi);
}
TEST(parse_pi_error_buffer_boundary)
{
char buf1[] = "<?name?>";
char buf2[] = "<?name?x";
xml_document doc;
CHECK(doc.load_buffer_inplace(buf1, 8, parse_fragment | parse_pi));
CHECK(doc.load_buffer_inplace(buf2, 8, parse_fragment | parse_pi).status == status_bad_pi);
}
TEST(parse_comments_skip)
{
xml_document doc;
@ -235,9 +247,9 @@ TEST(parse_ws_pcdata_skip)
CHECK(!doc.first_child());
CHECK(doc.load_string(STR("<root> <node> </node> </root>"), parse_minimal));
xml_node root = doc.child(STR("root"));
CHECK(root.first_child() == root.last_child());
CHECK(!root.first_child().first_child());
}
@ -280,46 +292,46 @@ TEST(parse_ws_pcdata_permutations)
struct test_data_t
{
unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
const pugi::char_t* source;
const pugi::char_t* result;
const char_t* source;
const char_t* result;
int nodes; // negative if parsing should fail
};
test_data_t test_data[] =
{
// external pcdata should be discarded (whitespace or not)
{7, STR("ext1<node/>"), STR("<node />"), 2},
{7, STR("ext1<node/>ext2"), STR("<node />"), 2},
{7, STR(" <node/>"), STR("<node />"), 2},
{7, STR("<node/> "), STR("<node />"), 2},
{7, STR(" <node/> "), STR("<node />"), 2},
{7, STR("ext1<node/>"), STR("<node/>"), 2},
{7, STR("ext1<node/>ext2"), STR("<node/>"), 2},
{7, STR(" <node/>"), STR("<node/>"), 2},
{7, STR("<node/> "), STR("<node/>"), 2},
{7, STR(" <node/> "), STR("<node/>"), 2},
// inner pcdata should be preserved
{7, STR("<node>inner</node>"), STR("<node>inner</node>"), 3},
{7, STR("<node>inner1<child/>inner2</node>"), STR("<node>inner1<child />inner2</node>"), 5},
{7, STR("<node>inner1<child/>inner2</node>"), STR("<node>inner1<child/>inner2</node>"), 5},
{7, STR("<node>inner1<child>deep</child>inner2</node>"), STR("<node>inner1<child>deep</child>inner2</node>"), 6},
// empty pcdata nodes should never be created
{7, STR("<node>inner1<child></child>inner2</node>"), STR("<node>inner1<child />inner2</node>"), 5},
{7, STR("<node><child></child>inner2</node>"), STR("<node><child />inner2</node>"), 4},
{7, STR("<node>inner1<child></child></node>"), STR("<node>inner1<child /></node>"), 4},
{7, STR("<node><child></child></node>"), STR("<node><child /></node>"), 3},
{7, STR("<node>inner1<child></child>inner2</node>"), STR("<node>inner1<child/>inner2</node>"), 5},
{7, STR("<node><child></child>inner2</node>"), STR("<node><child/>inner2</node>"), 4},
{7, STR("<node>inner1<child></child></node>"), STR("<node>inner1<child/></node>"), 4},
{7, STR("<node><child></child></node>"), STR("<node><child/></node>"), 3},
// comments, pi or other nodes should not cause pcdata creation either
{7, STR("<node><!----><child><?pi?></child><![CDATA[x]]></node>"), STR("<node><child /><![CDATA[x]]></node>"), 4},
{7, STR("<node><!----><child><?pi?></child><![CDATA[x]]></node>"), STR("<node><child/><![CDATA[x]]></node>"), 4},
// leading/trailing pcdata whitespace should be preserved (note: this will change if parse_ws_pcdata_trim is introduced)
{7, STR("<node>\t \tinner1<child> deep </child>\t\ninner2\n\t</node>"), STR("<node>\t \tinner1<child> deep </child>\t\ninner2\n\t</node>"), 6},
// whitespace-only pcdata preservation depends on the parsing mode
{1, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node><child /><child><deep /></child></node>"), 5},
{1, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node><child/><child><deep/></child></node>"), 5},
{2, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t\n\t</node>"), 13},
{4, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node><child> </child><child><deep> </deep></child></node>"), 7},
// current implementation of parse_ws_pcdata_single has an unfortunate bug; reproduce it here
{4, STR("<node>\t\t<!---->\n\n</node>"), STR("<node>\n\n</node>"), 3},
// error case: terminate PCDATA in the middle
{7, STR("<node>abcdef"), STR("<node>abcdef</node>"), -3},
{5, STR("<node> "), STR("<node />"), -2},
{5, STR("<node> "), STR("<node/>"), -2},
{2, STR("<node> "), STR("<node> </node>"), -3},
// error case: terminate PCDATA as early as possible
{7, STR("<node>"), STR("<node />"), -2},
{7, STR("<node>"), STR("<node/>"), -2},
{7, STR("<node>a"), STR("<node>a</node>"), -3},
{5, STR("<node> "), STR("<node />"), -2},
{5, STR("<node> "), STR("<node/>"), -2},
{2, STR("<node> "), STR("<node> </node>"), -3},
};
@ -349,8 +361,8 @@ TEST(parse_ws_pcdata_fragment_permutations)
struct test_data_t
{
unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
const pugi::char_t* source;
const pugi::char_t* result;
const char_t* source;
const char_t* result;
int nodes; // negative if parsing should fail
};
@ -360,18 +372,18 @@ TEST(parse_ws_pcdata_fragment_permutations)
{7, STR("ext1"), STR("ext1"), 2},
{5, STR(" "), STR(""), 1},
{2, STR(" "), STR(" "), 2},
{7, STR("ext1<node/>"), STR("ext1<node />"), 3},
{7, STR("<node/>ext2"), STR("<node />ext2"), 3},
{7, STR("ext1<node/>ext2"), STR("ext1<node />ext2"), 4},
{7, STR("ext1<node1/>ext2<node2/>ext3"), STR("ext1<node1 />ext2<node2 />ext3"), 6},
{5, STR(" <node/>"), STR("<node />"), 2},
{2, STR(" <node/>"), STR(" <node />"), 3},
{5, STR("<node/> "), STR("<node />"), 2},
{2, STR("<node/> "), STR("<node /> "), 3},
{5, STR(" <node/> "), STR("<node />"), 2},
{2, STR(" <node/> "), STR(" <node /> "), 4},
{5, STR(" <node1/> <node2/> "), STR("<node1 /><node2 />"), 3},
{2, STR(" <node1/> <node2/> "), STR(" <node1 /> <node2 /> "), 6},
{7, STR("ext1<node/>"), STR("ext1<node/>"), 3},
{7, STR("<node/>ext2"), STR("<node/>ext2"), 3},
{7, STR("ext1<node/>ext2"), STR("ext1<node/>ext2"), 4},
{7, STR("ext1<node1/>ext2<node2/>ext3"), STR("ext1<node1/>ext2<node2/>ext3"), 6},
{5, STR(" <node/>"), STR("<node/>"), 2},
{2, STR(" <node/>"), STR(" <node/>"), 3},
{5, STR("<node/> "), STR("<node/>"), 2},
{2, STR("<node/> "), STR("<node/> "), 3},
{5, STR(" <node/> "), STR("<node/>"), 2},
{2, STR(" <node/> "), STR(" <node/> "), 4},
{5, STR(" <node1/> <node2/> "), STR("<node1/><node2/>"), 3},
{2, STR(" <node1/> <node2/> "), STR(" <node1/> <node2/> "), 6},
};
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
@ -429,8 +441,8 @@ TEST(parse_pcdata_trim)
{
struct test_data_t
{
const pugi::char_t* source;
const pugi::char_t* result;
const char_t* source;
const char_t* result;
unsigned int flags;
};
@ -462,7 +474,7 @@ TEST(parse_pcdata_trim)
xml_document doc;
CHECK(doc.load_string(td.source, td.flags | parse_trim_pcdata));
const pugi::char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get();
const char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get();
CHECK_STRING(value, td.result);
}
}
@ -551,7 +563,7 @@ TEST(parse_escapes_unicode)
CHECK(doc.load_string(STR("<node>&#x03B3;&#x03b3;&#x24B62;</node>"), parse_minimal | parse_escapes));
#ifdef PUGIXML_WCHAR_MODE
const pugi::char_t* v = doc.child_value(STR("node"));
const char_t* v = doc.child_value(STR("node"));
size_t wcharsize = sizeof(wchar_t);
@ -746,18 +758,48 @@ TEST(parse_attribute_quot_inside)
}
}
TEST(parse_attribute_wnorm_coverage)
{
xml_document doc;
CHECK(doc.load_string(STR("<n a1='v' a2=' ' a3='x y' a4='x y' a5='x y' />"), parse_wnorm_attribute));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"\" a3=\"x y\" a4=\"x y\" a5=\"x y\"/>"));
CHECK(doc.load_string(STR("<n a1='v' a2=' ' a3='x y' a4='x y' a5='x y' />"), parse_wnorm_attribute | parse_escapes));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"\" a3=\"x y\" a4=\"x y\" a5=\"x y\"/>"));
}
TEST(parse_attribute_wconv_coverage)
{
xml_document doc;
CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_wconv_attribute));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\" \" a3=\" \" a4=\" \"/>"));
CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_wconv_attribute | parse_escapes));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\" \" a3=\" \" a4=\" \"/>"));
}
TEST(parse_attribute_eol_coverage)
{
xml_document doc;
CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_eol));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"&#10;\" a3=\"&#10;&#10;\" a4=\"&#10;\"/>"));
CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_eol | parse_escapes));
CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"&#10;\" a3=\"&#10;&#10;\" a4=\"&#10;\"/>"));
}
TEST(parse_tag_single)
{
xml_document doc;
CHECK(doc.load_string(STR("<node/><node /><node\n/>"), parse_minimal));
CHECK_NODE(doc, STR("<node /><node /><node />"));
CHECK_NODE(doc, STR("<node/><node/><node/>"));
}
TEST(parse_tag_hierarchy)
{
xml_document doc;
CHECK(doc.load_string(STR("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>"), parse_minimal));
CHECK_NODE(doc, STR("<node><n1><n2 /></n1><n3><n4><n5 /></n4></n3></node>"));
CHECK_NODE(doc, STR("<node><n1><n2/></n1><n3><n4><n5/></n4></n3></node>"));
}
TEST(parse_tag_error)
@ -855,7 +897,7 @@ TEST(parse_declaration_error)
CHECK(doc.load_string(STR("<?xml>"), flags).status == status_bad_pi);
CHECK(doc.load_string(STR("<?xml version='1>"), flags).status == status_bad_pi);
}
CHECK(doc.load_string(STR("<?xml version='1?>"), parse_fragment | parse_declaration).status == status_bad_attribute);
CHECK(doc.load_string(STR("<foo><?xml version='1'?></foo>"), parse_fragment | parse_declaration).status == status_bad_pi);
}
@ -893,8 +935,8 @@ TEST(parse_out_of_memory_halfway_node)
test_runner::_memory_fail_threshold = 65536;
xml_document doc;
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory));
CHECK_NODE(doc.first_child(), STR("<n />"));
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
CHECK_NODE(doc.first_child(), STR("<n/>"));
}
TEST(parse_out_of_memory_halfway_attr)
@ -920,7 +962,7 @@ TEST(parse_out_of_memory_halfway_attr)
test_runner::_memory_fail_threshold = 65536;
xml_document doc;
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 5 + 4).status == status_out_of_memory));
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
CHECK_STRING(doc.first_child().name(), STR("n"));
CHECK_STRING(doc.first_child().first_attribute().name(), STR("a"));
CHECK_STRING(doc.first_child().last_attribute().name(), STR("a"));
@ -928,7 +970,7 @@ TEST(parse_out_of_memory_halfway_attr)
TEST(parse_out_of_memory_conversion)
{
test_runner::_memory_fail_threshold = 256;
test_runner::_memory_fail_threshold = 1;
xml_document doc;
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer("<foo\x90/>", 7, parse_default, encoding_latin1).status == status_out_of_memory));
@ -951,8 +993,8 @@ TEST(parse_out_of_memory_allocator_state_sync)
test_runner::_memory_fail_threshold = 65536;
xml_document doc;
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, count * 4).status == status_out_of_memory));
CHECK_NODE(doc.first_child(), STR("<n />"));
CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
CHECK_NODE(doc.first_child(), STR("<n/>"));
test_runner::_memory_fail_threshold = 0;
@ -960,7 +1002,7 @@ TEST(parse_out_of_memory_allocator_state_sync)
CHECK(doc.append_child(STR("n")));
}
static bool test_offset(const char_t* contents, unsigned int options, pugi::xml_parse_status status, ptrdiff_t offset)
static bool test_offset(const char_t* contents, unsigned int options, xml_parse_status status, ptrdiff_t offset)
{
xml_document doc;
xml_parse_result res = doc.load_string(contents, options);
@ -1005,8 +1047,8 @@ TEST(parse_error_offset)
CHECK_OFFSET("<n></n $>", parse_default, status_bad_end_element, 7);
CHECK_OFFSET("<n></n", parse_default, status_bad_end_element, 5);
CHECK_OFFSET("<no></na>", parse_default, status_end_element_mismatch, 8);
CHECK_OFFSET("<no></nod>", parse_default, status_end_element_mismatch, 9);
CHECK_OFFSET("<no></na>", parse_default, status_end_element_mismatch, 6);
CHECK_OFFSET("<no></nod>", parse_default, status_end_element_mismatch, 6);
}
TEST(parse_result_default)
@ -1139,3 +1181,177 @@ TEST(parse_fuzz_doctype)
xml_document doc;
CHECK(doc.load_buffer(data, sizeof(data)).status == status_bad_doctype);
}
TEST(parse_embed_pcdata)
{
// parse twice - once with default and once with embed_pcdata flags
for (int i = 0; i < 2; ++i)
{
unsigned int flags = (i == 0) ? parse_default : parse_default | parse_embed_pcdata;
xml_document doc;
xml_parse_result res = doc.load_string(STR("<node><key>value</key><child><inner1>value1</inner1><inner2>value2</inner2>outer</child><two>text<data /></two></node>"), flags);
CHECK(res);
xml_node child = doc.child(STR("node")).child(STR("child"));
// parse_embed_pcdata omits PCDATA nodes so DOM is different
if (flags & parse_embed_pcdata)
{
CHECK_STRING(doc.child(STR("node")).child(STR("key")).value(), STR("value"));
CHECK(!doc.child(STR("node")).child(STR("key")).first_child());
}
else
{
CHECK_STRING(doc.child(STR("node")).child(STR("key")).value(), STR(""));
CHECK(doc.child(STR("node")).child(STR("key")).first_child());
CHECK_STRING(doc.child(STR("node")).child(STR("key")).first_child().value(), STR("value"));
}
// higher-level APIs work the same though
CHECK_STRING(child.text().get(), STR("outer"));
CHECK_STRING(child.child(STR("inner1")).text().get(), STR("value1"));
CHECK_STRING(child.child_value(), STR("outer"));
CHECK_STRING(child.child_value(STR("inner2")), STR("value2"));
#ifndef PUGIXML_NO_XPATH
CHECK_XPATH_NUMBER(doc, STR("count(node/child/*[starts-with(., 'value')])"), 2);
#endif
CHECK_NODE(doc, STR("<node><key>value</key><child><inner1>value1</inner1><inner2>value2</inner2>outer</child><two>text<data/></two></node>"));
CHECK_NODE_EX(doc, STR("<node>\n<key>value</key>\n<child>\n<inner1>value1</inner1>\n<inner2>value2</inner2>outer</child>\n<two>text<data />\n</two>\n</node>\n"), STR("\t"), 0);
CHECK_NODE_EX(doc, STR("<node>\n\t<key>value</key>\n\t<child>\n\t\t<inner1>value1</inner1>\n\t\t<inner2>value2</inner2>outer</child>\n\t<two>text<data />\n\t</two>\n</node>\n"), STR("\t"), format_indent);
}
}
TEST_XML_FLAGS(parse_embed_pcdata_fragment, "text", parse_fragment | parse_embed_pcdata)
{
CHECK_NODE(doc, STR("text"));
CHECK(doc.first_child().type() == node_pcdata);
CHECK_STRING(doc.first_child().value(), STR("text"));
}
TEST_XML_FLAGS(parse_embed_pcdata_child, "<n><child/>text</n>", parse_embed_pcdata)
{
xml_node n = doc.child(STR("n"));
CHECK_NODE(doc, STR("<n><child/>text</n>"));
CHECK(n.last_child().type() == node_pcdata);
CHECK_STRING(n.last_child().value(), STR("text"));
}
TEST_XML_FLAGS(parse_embed_pcdata_comment, "<n>text1<!---->text2</n>", parse_embed_pcdata)
{
xml_node n = doc.child(STR("n"));
CHECK_NODE(doc, STR("<n>text1text2</n>"));
CHECK_STRING(n.value(), STR("text1"));
CHECK(n.first_child() == n.last_child());
CHECK(n.last_child().type() == node_pcdata);
CHECK_STRING(n.last_child().value(), STR("text2"));
}
TEST(parse_encoding_detect)
{
char test[] = "<?xml version='1.0' encoding='utf-8'?><n/>";
xml_document doc;
CHECK(doc.load_buffer(test, sizeof(test)));
}
TEST(parse_encoding_detect_latin1)
{
char test0[] = "<?xml version='1.0' encoding='utf-8'?><n/>";
char test1[] = "<?xml version='1.0' encoding='iso-8859-1'?><n/>";
char test2[] = "<?xml version='1.0' encoding = \"latin1\"?><n/>";
char test3[] = "<?xml version='1.0' encoding='ISO-8859-1'?><n/>";
char test4[] = "<?xml version='1.0' encoding = \"LATIN1\"?><n/>";
xml_document doc;
CHECK(doc.load_buffer(test0, sizeof(test0)).encoding == encoding_utf8);
CHECK(doc.load_buffer(test1, sizeof(test1)).encoding == encoding_latin1);
CHECK(doc.load_buffer(test2, sizeof(test2)).encoding == encoding_latin1);
CHECK(doc.load_buffer(test3, sizeof(test3)).encoding == encoding_latin1);
CHECK(doc.load_buffer(test4, sizeof(test4)).encoding == encoding_latin1);
}
TEST(parse_encoding_detect_auto)
{
struct data_t
{
const char* contents;
size_t size;
xml_encoding encoding;
};
const data_t data[] =
{
// BOM
{ "\x00\x00\xfe\xff", 4, encoding_utf32_be },
{ "\xff\xfe\x00\x00", 4, encoding_utf32_le },
{ "\xfe\xff ", 4, encoding_utf16_be },
{ "\xff\xfe ", 4, encoding_utf16_le },
{ "\xef\xbb\xbf ", 4, encoding_utf8 },
// automatic tag detection for < or <?
{ "\x00\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>", 16, encoding_utf32_be },
{ "<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 16, encoding_utf32_le },
{ "\x00<\x00?\x00n\x00?\x00>", 10, encoding_utf16_be },
{ "<\x00?\x00n\x00?\x00>\x00", 10, encoding_utf16_le },
{ "\x00<\x00n\x00/\x00>", 8, encoding_utf16_be },
{ "<\x00n\x00/\x00>\x00", 8, encoding_utf16_le },
// <?xml encoding
{ "<?xml encoding='latin1'?>", 25, encoding_latin1 },
};
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
{
xml_document doc;
xml_parse_result result = doc.load_buffer(data[i].contents, data[i].size, parse_fragment);
CHECK(result);
CHECK(result.encoding == data[i].encoding);
}
}
TEST(parse_encoding_detect_auto_incomplete)
{
struct data_t
{
const char* contents;
size_t size;
xml_encoding encoding;
};
const data_t data[] =
{
// BOM
{ "\x00\x00\xfe ", 4, encoding_utf8 },
{ "\x00\x00 ", 4, encoding_utf8 },
{ "\xff\xfe\x00 ", 4, encoding_utf16_le },
{ "\xfe ", 4, encoding_utf8 },
{ "\xff ", 4, encoding_utf8 },
{ "\xef\xbb ", 4, encoding_utf8 },
{ "\xef ", 4, encoding_utf8 },
// automatic tag detection for < or <?
{ "\x00\x00\x00 ", 4, encoding_utf8 },
{ "<\x00\x00n/\x00>\x00", 8, encoding_utf16_le },
{ "\x00<n\x00\x00/\x00>", 8, encoding_utf16_be },
{ "<\x00?n/\x00>\x00", 8, encoding_utf16_le },
{ "\x00 ", 2, encoding_utf8 },
// <?xml encoding
{ "<?xmC encoding='latin1'?>", 25, encoding_utf8 },
{ "<?xBC encoding='latin1'?>", 25, encoding_utf8 },
{ "<?ABC encoding='latin1'?>", 25, encoding_utf8 },
{ "<_ABC encoding='latin1'/>", 25, encoding_utf8 },
};
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
{
xml_document doc;
xml_parse_result result = doc.load_buffer(data[i].contents, data[i].size, parse_fragment);
CHECK(result);
CHECK(result.encoding == data[i].encoding);
}
}

View file

@ -1,11 +1,13 @@
#define _CRT_SECURE_NO_WARNINGS
#include "common.hpp"
#include "test.hpp"
#include <string.h>
#include <wchar.h>
#include <string>
using namespace pugi;
static xml_parse_result load_concat(xml_document& doc, const char_t* a, const char_t* b = STR(""), const char_t* c = STR(""))
{
char_t buffer[768];
@ -36,9 +38,9 @@ static bool test_doctype_wf(const char_t* decl)
if (!load_concat(doc, STR("a"), decl, STR("b")) || !test_node(doc, STR("ab"), STR(""), format_raw)) return false;
// node pre/postfix
if (!load_concat(doc, STR("<nodea/>"), decl) || !test_node(doc, STR("<nodea />"), STR(""), format_raw)) return false;
if (!load_concat(doc, decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodeb />"), STR(""), format_raw)) return false;
if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea /><nodeb />"), STR(""), format_raw)) return false;
if (!load_concat(doc, STR("<nodea/>"), decl) || !test_node(doc, STR("<nodea/>"), STR(""), format_raw)) return false;
if (!load_concat(doc, decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodeb/>"), STR(""), format_raw)) return false;
if (!load_concat(doc, STR("<nodea/>"), decl, STR("<nodeb/>")) || !test_node(doc, STR("<nodea/><nodeb/>"), STR(""), format_raw)) return false;
// check load-store contents preservation
CHECK(doc.load_string(decl, parse_doctype | parse_fragment));
@ -219,7 +221,7 @@ TEST(parse_doctype_xmlconf_ibm_2)
TEST_DOCTYPE_NWF("<!DOCTYPE animal [ <!ELEMENT animal ANY> <!ENTITY % parameterE \"A music file ?>\"> <?music %parameterE; ]>");
TEST_DOCTYPE_NWF("<!DOCTYPE animal [ <!ELEMENT animal ANY> <!ENTITY % parameterE \"leopard EMPTY>\"> <!ELEMENT %parameterE; ]>");
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root ANY> <!ATTLIST root attr1 CDATA #IMPLIED> <!ATTLIST root attr2 CDATA #IMPLIED> <!ENTITY withlt \"have <lessthan> inside\"> <!ENTITY aIndirect \"&withlt;\"> ]>");
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root (#PCDATA)> <!--* Mising Name S contentspec in elementdecl *--> <!ELEMENT > ]>");
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root (#PCDATA)> <!--* Missing Name S contentspec in elementdecl *--> <!ELEMENT > ]>");
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root (#PCDATA)> <!ELEMENT a ANY> <!ELEMENT b ANY> <!--* extra separator in seq *--> <!ELEMENT aElement ((a|b),,a)? > ]>");
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root (#PCDATA)> <!ELEMENT a ANY> <!--* Missing white space before Name in AttDef *--> <!ATTLIST a attr1 CDATA \"default\"attr2 ID #required> ]>");
TEST_DOCTYPE_WF("<!DOCTYPE test [ <!ELEMENT test ANY> <!ELEMENT one EMPTY> <!ELEMENT two EMPTY> <!NOTATION this SYSTEM \"alpha\"> <!ATTLIST three attr NOTATION (\"this\") #IMPLIED> ]>");

View file

@ -1,9 +1,11 @@
#ifndef PUGIXML_NO_STL
#include "common.hpp"
#include "test.hpp"
#include <string>
using namespace pugi;
// letters taken from http://www.utf8-chartable.de/
TEST(as_wide_empty)

View file

@ -1,5 +1,5 @@
#include "../src/pugixml.hpp"
#if PUGIXML_VERSION != 170
#if PUGIXML_VERSION != 1130
#error Unexpected pugixml version
#endif

View file

@ -1,4 +1,4 @@
#include "common.hpp"
#include "test.hpp"
#include "writer_string.hpp"
@ -6,6 +6,8 @@
#include <sstream>
#include <stdexcept>
using namespace pugi;
TEST_XML(write_simple, "<node attr='1'><child>text</child></node>")
{
CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n<child>text</child>\n</node>\n"), STR(""), 0);
@ -69,6 +71,12 @@ TEST_XML_FLAGS(write_cdata_escape, "<![CDATA[value]]>", parse_cdata | parse_frag
doc.first_child().set_value(STR("1]]>2]]>3"));
CHECK_NODE(doc, STR("<![CDATA[1]]]]><![CDATA[>2]]]]><![CDATA[>3]]>"));
doc.first_child().set_value(STR("1]"));
CHECK_NODE(doc, STR("<![CDATA[1]]]>"));
doc.first_child().set_value(STR("1]]"));
CHECK_NODE(doc, STR("<![CDATA[1]]]]>"));
}
TEST_XML(write_cdata_inner, "<node><![CDATA[value]]></node>")
@ -185,19 +193,35 @@ TEST_XML(write_escape, "<node attr=''>text</node>")
doc.child(STR("node")).attribute(STR("attr")) = STR("<>'\"&\x04\r\n\t");
doc.child(STR("node")).first_child().set_value(STR("<>'\"&\x04\r\n\t"));
CHECK_NODE(doc, STR("<node attr=\"&lt;&gt;'&quot;&amp;&#04;&#13;&#10;\t\">&lt;&gt;'\"&amp;&#04;\r\n\t</node>"));
CHECK_NODE(doc, STR("<node attr=\"&lt;>'&quot;&amp;&#04;&#13;&#10;&#09;\">&lt;&gt;'\"&amp;&#04;\r\n\t</node>"));
CHECK_NODE_EX(doc, STR("<node attr='&lt;>&apos;\"&amp;&#04;&#13;&#10;&#09;'>&lt;&gt;'\"&amp;&#04;\r\n\t</node>"), STR(""), format_raw | format_attribute_single_quote);
}
TEST_XML(write_escape_roundtrip, "<node attr=''>text</node>")
{
doc.child(STR("node")).attribute(STR("attr")) = STR("<>'\"&\x04\r\n\t");
doc.child(STR("node")).first_child().set_value(STR("<>'\"&\x04\r\n\t"));
std::string contents = write_narrow(doc, format_raw, encoding_utf8);
CHECK(doc.load_buffer(contents.c_str(), contents.size()));
// Note: this string is almost identical to the string from write_escape with the exception of \r
// \r in PCDATA doesn't roundtrip because it has to go through newline conversion (which could be disabled, but is active by default)
CHECK_NODE(doc, STR("<node attr=\"&lt;>'&quot;&amp;&#04;&#13;&#10;&#09;\">&lt;&gt;'\"&amp;&#04;\n\t</node>"));
CHECK_NODE_EX(doc, STR("<node attr='&lt;>&apos;\"&amp;&#04;&#13;&#10;&#09;'>&lt;&gt;'\"&amp;&#04;\n\t</node>"), STR(""), format_raw | format_attribute_single_quote);
}
TEST_XML(write_escape_unicode, "<node attr='&#x3c00;'/>")
{
#ifdef PUGIXML_WCHAR_MODE
#ifdef U_LITERALS
CHECK_NODE(doc, STR("<node attr=\"\u3c00\" />"));
CHECK_NODE(doc, STR("<node attr=\"\u3c00\"/>"));
#else
CHECK_NODE(doc, STR("<node attr=\"\x3c00\" />"));
CHECK_NODE(doc, STR("<node attr=\"\x3c00\"/>"));
#endif
#else
CHECK_NODE(doc, STR("<node attr=\"\xe3\xb0\x80\" />"));
CHECK_NODE(doc, STR("<node attr=\"\xe3\xb0\x80\"/>"));
#endif
}
@ -211,12 +235,12 @@ TEST_XML(write_no_escapes, "<node attr=''>text</node>")
struct test_writer: xml_writer
{
std::basic_string<pugi::char_t> contents;
std::basic_string<char_t> contents;
virtual void write(const void* data, size_t size)
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE
{
CHECK(size % sizeof(pugi::char_t) == 0);
contents.append(static_cast<const pugi::char_t*>(data), size / sizeof(pugi::char_t));
CHECK(size % sizeof(char_t) == 0);
contents.append(static_cast<const char_t*>(data), size / sizeof(char_t));
}
};
@ -256,7 +280,7 @@ TEST_XML(write_print_stream_wide, "<node/>")
TEST_XML(write_huge_chunk, "<node/>")
{
std::basic_string<pugi::char_t> name(10000, STR('n'));
std::basic_string<char_t> name(10000, STR('n'));
doc.child(STR("node")).set_name(name.c_str());
test_writer writer;
@ -473,7 +497,7 @@ TEST(write_no_name_element)
root.append_child();
root.append_child().append_child(node_pcdata).set_value(STR("text"));
CHECK_NODE(doc, STR("<:anonymous><:anonymous /><:anonymous>text</:anonymous></:anonymous>"));
CHECK_NODE(doc, STR("<:anonymous><:anonymous/><:anonymous>text</:anonymous></:anonymous>"));
CHECK_NODE_EX(doc, STR("<:anonymous>\n\t<:anonymous />\n\t<:anonymous>text</:anonymous>\n</:anonymous>\n"), STR("\t"), format_default);
}
@ -491,7 +515,7 @@ TEST(write_no_name_attribute)
doc.append_child().set_name(STR("root"));
doc.child(STR("root")).append_attribute(STR(""));
CHECK_NODE(doc, STR("<root :anonymous=\"\" />"));
CHECK_NODE(doc, STR("<root :anonymous=\"\"/>"));
}
TEST(write_print_empty)
@ -517,7 +541,7 @@ TEST(write_print_stream_empty_wide)
TEST(write_stackless)
{
unsigned int count = 20000;
std::basic_string<pugi::char_t> data;
std::basic_string<char_t> data;
for (unsigned int i = 0; i < count; ++i)
data += STR("<a>");
@ -596,15 +620,74 @@ TEST(write_pcdata_whitespace_fixedpoint)
TEST_XML_FLAGS(write_mixed, "<node><child1/><child2>pre<![CDATA[data]]>mid<!--comment--><test/>post<?pi value?>fin</child2><child3/></node>", parse_full)
{
CHECK_NODE(doc, STR("<node><child1 /><child2>pre<![CDATA[data]]>mid<!--comment--><test />post<?pi value?>fin</child2><child3 /></node>"));
CHECK_NODE(doc, STR("<node><child1/><child2>pre<![CDATA[data]]>mid<!--comment--><test/>post<?pi value?>fin</child2><child3/></node>"));
CHECK_NODE_EX(doc, STR("<node>\n<child1 />\n<child2>pre<![CDATA[data]]>mid<!--comment-->\n<test />post<?pi value?>fin</child2>\n<child3 />\n</node>\n"), STR("\t"), 0);
CHECK_NODE_EX(doc, STR("<node>\n\t<child1 />\n\t<child2>pre<![CDATA[data]]>mid<!--comment-->\n\t\t<test />post<?pi value?>fin</child2>\n\t<child3 />\n</node>\n"), STR("\t"), format_indent);
}
#ifndef PUGIXML_NO_EXCEPTIONS
struct throwing_writer: pugi::xml_writer
TEST_XML(write_no_empty_element_tags, "<node><child1/><child2>text</child2><child3></child3></node>")
{
virtual void write(const void*, size_t)
CHECK_NODE(doc, STR("<node><child1/><child2>text</child2><child3/></node>"));
CHECK_NODE_EX(doc, STR("<node><child1></child1><child2>text</child2><child3></child3></node>"), STR("\t"), format_raw | format_no_empty_element_tags);
CHECK_NODE_EX(doc, STR("<node>\n\t<child1></child1>\n\t<child2>text</child2>\n\t<child3></child3>\n</node>\n"), STR("\t"), format_indent | format_no_empty_element_tags);
}
TEST_XML_FLAGS(write_roundtrip, "<node><child1 attr1='value1' attr2='value2'/><child2 attr='value'>pre<![CDATA[data]]>mid&lt;text&amp;escape<!--comment--><test/>post<?pi value?>fin</child2><child3/></node>", parse_full)
{
const unsigned int flagset[] = { format_indent, format_raw, format_no_declaration, format_indent_attributes, format_no_empty_element_tags, format_attribute_single_quote };
size_t flagcount = sizeof(flagset) / sizeof(flagset[0]);
for (size_t i = 0; i < (size_t(1) << flagcount); ++i)
{
unsigned int flags = 0;
for (size_t j = 0; j < flagcount; ++j)
if (i & (size_t(1) << j))
flags |= flagset[j];
std::string contents = write_narrow(doc, flags, encoding_utf8);
xml_document verify;
CHECK(verify.load_buffer(contents.c_str(), contents.size(), parse_full));
CHECK(test_write_narrow(verify, flags, encoding_utf8, contents.c_str(), contents.size()));
xml_document verifyws;
CHECK(verifyws.load_buffer(contents.c_str(), contents.size(), parse_full | parse_ws_pcdata));
CHECK(test_write_narrow(verifyws, flags, encoding_utf8, contents.c_str(), contents.size()));
}
}
TEST(write_flush_coverage)
{
xml_document doc;
// this creates a node that uses short sequences of lengths 1-6 for output
xml_node n = doc.append_child(STR("n"));
xml_attribute a = n.append_attribute(STR("a"));
xml_attribute b = n.append_attribute(STR("b"));
b.set_value(STR("<&\""));
n.append_child(node_comment);
size_t basel = save_narrow(doc, format_raw, encoding_auto).size();
size_t bufl = 2048;
for (size_t l = 0; l <= basel; ++l)
{
std::basic_string<char_t> pad(bufl - l, STR('v'));
a.set_value(pad.c_str());
std::string s = save_narrow(doc, format_raw, encoding_auto);
CHECK(s.size() == basel + bufl - l);
}
}
#ifndef PUGIXML_NO_EXCEPTIONS
struct throwing_writer: xml_writer
{
virtual void write(const void*, size_t) PUGIXML_OVERRIDE
{
throw std::runtime_error("write failed");
}
@ -638,3 +721,13 @@ TEST_XML(write_throw_encoding, "<node><child/></node>")
}
}
#endif
TEST_XML(write_skip_control_chars, "<a>\f\t\n\x0F\x19</a>")
{
CHECK_NODE_EX(doc.first_child(), STR("<a>\t\n</a>\n"), STR(""), pugi::format_default | pugi::format_skip_control_chars);
}
TEST_XML(write_keep_control_chars, "<a>\f\t\n\x0F\x19</a>")
{
CHECK_NODE_EX(doc.first_child(), STR("<a>&#12;\t\n&#15;&#25;</a>\n"), STR(""), pugi::format_default);
}

View file

@ -1,6 +1,6 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
#include <string.h>
#include <wchar.h>
@ -10,6 +10,8 @@
#include <algorithm>
#include <limits>
using namespace pugi;
static void load_document_copy(xml_document& doc, const char_t* text)
{
xml_document source;
@ -18,6 +20,22 @@ static void load_document_copy(xml_document& doc, const char_t* text)
doc.append_copy(source.first_child());
}
template <typename T>
static void random_shuffle(std::vector<T>& v)
{
size_t rng = 2147483647;
for (size_t i = v.size() - 1; i > 0; --i)
{
// Fisher-Yates shuffle
size_t j = rng % (i + 1);
std::swap(v[j], v[i]);
// LCG RNG, constants from Numerical Recipes
rng = rng * 1664525 + 1013904223;
}
}
TEST(xpath_allocator_many_pages)
{
std::basic_string<char_t> query = STR("0");
@ -153,7 +171,7 @@ TEST(xpath_sort_random_medium)
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
std::vector<xpath_node> nsv(ns.begin(), ns.end());
std::random_shuffle(nsv.begin(), nsv.end());
random_shuffle(nsv);
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
copy.sort();
@ -182,7 +200,7 @@ TEST(xpath_sort_random_large)
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
std::vector<xpath_node> nsv(ns.begin(), ns.end());
std::random_shuffle(nsv.begin(), nsv.end());
random_shuffle(nsv);
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
copy.sort();
@ -194,40 +212,40 @@ TEST(xpath_sort_random_large)
TEST(xpath_long_numbers_parse)
{
const pugi::char_t* str_flt_max = STR("340282346638528860000000000000000000000");
const pugi::char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
const pugi::char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
const pugi::char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
const char_t* str_flt_max = STR("340282346638528860000000000000000000000");
const char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
const char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
const char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
xml_node c;
// check parsing
CHECK_XPATH_NUMBER(c, str_flt_max, std::numeric_limits<float>::max());
CHECK_XPATH_NUMBER(c, str_flt_max_dec, std::numeric_limits<float>::max());
CHECK_XPATH_NUMBER(c, str_flt_max, double(std::numeric_limits<float>::max()));
CHECK_XPATH_NUMBER(c, str_flt_max_dec, double(std::numeric_limits<float>::max()));
CHECK_XPATH_NUMBER(c, str_dbl_max, std::numeric_limits<double>::max());
CHECK_XPATH_NUMBER(c, str_dbl_max_dec, std::numeric_limits<double>::max());
}
static bool test_xpath_string_prefix(const pugi::xml_node& node, const pugi::char_t* query, const pugi::char_t* expected, size_t match_length)
static bool test_xpath_string_prefix(const xml_node& node, const char_t* query, const char_t* expected, size_t match_length)
{
pugi::xpath_query q(query);
xpath_query q(query);
pugi::char_t result[32];
char_t result[32];
size_t size = q.evaluate_string(result, sizeof(result) / sizeof(result[0]), node);
size_t expected_length = std::char_traits<pugi::char_t>::length(expected);
size_t expected_length = std::char_traits<char_t>::length(expected);
return size == expected_length + 1 && std::char_traits<pugi::char_t>::compare(result, expected, match_length) == 0;
return size == expected_length + 1 && std::char_traits<char_t>::compare(result, expected, match_length) == 0;
}
TEST(xpath_long_numbers_stringize)
{
const pugi::char_t* str_flt_max = STR("340282346638528860000000000000000000000");
const pugi::char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
const pugi::char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
const pugi::char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
const char_t* str_flt_max = STR("340282346638528860000000000000000000000");
const char_t* str_flt_max_dec = STR("340282346638528860000000000000000000000.000000");
const char_t* str_dbl_max = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
const char_t* str_dbl_max_dec = STR("179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000");
xml_node c;
@ -240,7 +258,7 @@ TEST(xpath_long_numbers_stringize)
TEST(xpath_denorm_numbers)
{
std::basic_string<pugi::char_t> query;
std::basic_string<char_t> query;
// 10^-318 - double denormal
for (int i = 0; i < 106; ++i)
@ -249,7 +267,13 @@ TEST(xpath_denorm_numbers)
query += STR("0.001");
}
CHECK_XPATH_STRING(xml_node(), query.c_str(), STR("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999987484955998"));
// check if current fpu setup supports denormals
double denorm = xpath_query(query.c_str()).evaluate_number(xml_node());
if (denorm != 0.0)
{
CHECK_XPATH_STRING(xml_node(), query.c_str(), STR("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999987484955998"));
}
}
TEST_XML(xpath_rexml_1, "<a><b><c id='a'/></b><c id='b'/></a>")
@ -367,6 +391,36 @@ TEST(xpath_large_node_set)
CHECK(ns.size() == 10001);
}
TEST(xpath_out_of_memory_query)
{
test_runner::_memory_fail_threshold = 1;
CHECK_ALLOC_FAIL(xpath_query q(STR("node")));
}
TEST_XML(xpath_out_of_memory_evaluate, "<n/>")
{
test_runner::_memory_fail_threshold = 4196 * sizeof(char_t) + 4096 * 2 + 32768;
std::basic_string<char_t> query = STR("*[concat(\"a\", \"");
query.resize(4196, 'a');
query += STR("\")]");
xpath_query q(query.c_str());
CHECK_ALLOC_FAIL(CHECK(q.evaluate_boolean(doc) == false));
CHECK_ALLOC_FAIL(CHECK_DOUBLE_NAN(q.evaluate_number(doc)));
#ifndef PUGIXML_NO_STL
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(doc).empty()));
#endif
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc) == 1));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node(doc) == xpath_node()));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc).empty()));
}
TEST(xpath_out_of_memory_evaluate_concat)
{
test_runner::_memory_fail_threshold = 4196 * sizeof(char_t) + 4096 * 2;
@ -376,7 +430,23 @@ TEST(xpath_out_of_memory_evaluate_concat)
query.resize(4196, 'a');
query += STR("\")");
pugi::xpath_query q(query.c_str());
xpath_query q(query.c_str());
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
}
TEST(xpath_out_of_memory_evaluate_concat_list)
{
std::basic_string<char_t> query = STR("concat(");
for (size_t i = 0; i < 500; ++i)
query += STR("\"\",");
query += STR("\"\")");
xpath_query q(query.c_str());
test_runner::_memory_fail_threshold = 1;
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
}
@ -390,43 +460,151 @@ TEST(xpath_out_of_memory_evaluate_substring)
query.resize(4196, 'a');
query += STR("\", 1, 4097)");
pugi::xpath_query q(query.c_str());
xpath_query q(query.c_str());
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
}
TEST_XML(xpath_out_of_memory_evaluate_union, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
TEST_XML(xpath_out_of_memory_evaluate_union, "<node />")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
// left hand side: size * sizeof(xpath_node) (8 on 32-bit, 16 on 64-bit)
// right hand side: same
// to make sure that when we append right hand side to left hand side, we run out of an XPath stack page (4K), we need slightly more than 2K/8 = 256 nodes on 32-bit, 128 nodes on 64-bit
size_t count = sizeof(void*) == 4 ? 300 : 150;
pugi::xpath_query q(STR("a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|(a|a)))))))))))))))))))"));
for (size_t i = 0; i < count; ++i)
doc.first_child().append_child(STR("a"));
xpath_query q(STR("a|a"));
test_runner::_memory_fail_threshold = 1;
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc.child(STR("node"))).empty()));
}
TEST_XML(xpath_out_of_memory_evaluate_predicate, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
TEST_XML(xpath_out_of_memory_evaluate_union_hash, "<node />")
{
// left hand side: size * sizeof(xpath_node) (8 on 32-bit, 16 on 64-bit)
// right hand side: same
// hash table: size * 1.5 * sizeof(void*)
// to make sure that when we append right hand side to left hand side, we do *not* run out of an XPath stack page (4K), we need slightly less than 2K/8 = 256 nodes on 32-bit, 128 nodes on 64-bit
size_t count = sizeof(void*) == 4 ? 200 : 100;
for (size_t i = 0; i < count; ++i)
doc.first_child().append_child(STR("a"));
xpath_query q(STR("a|a"));
test_runner::_memory_fail_threshold = 1;
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc.child(STR("node"))).empty()));
}
TEST_XML(xpath_out_of_memory_evaluate_predicate, "<node><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/><a/></node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
pugi::xpath_query q(STR("//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[//a[true()]]]]]]]]]]]]]]"));
xpath_query q(STR("//a[//a[//a[//a[true()]]]]"));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc).empty()));
}
TEST_XML(xpath_out_of_memory_evaluate_normalize_space_0, "<node> a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z </node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
xpath_query q(STR("concat(normalize-space(), normalize-space(), normalize-space(), normalize-space(), normalize-space(), normalize-space(), normalize-space(), normalize-space())"));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc.first_child()) == 1));
}
TEST_XML(xpath_out_of_memory_evaluate_normalize_space_1, "<node> a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z </node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
xpath_query q(STR("concat(normalize-space(node), normalize-space(node), normalize-space(node), normalize-space(node), normalize-space(node), normalize-space(node), normalize-space(node), normalize-space(node))"));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc) == 1));
}
TEST_XML(xpath_out_of_memory_evaluate_translate, "<node> a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z </node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
xpath_query q(STR("concat(translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'), translate(node, 'a', '\xe9'))"));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc) == 1));
}
TEST_XML(xpath_out_of_memory_evaluate_translate_table, "<node> a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z a b c d e f g h i j k l m n o p q r s t u v w x y z </node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
xpath_query q(STR("concat(translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'), translate(node, 'a', 'A'))"));
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc) == 1));
}
TEST(xpath_out_of_memory_evaluate_string_append)
{
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
std::basic_string<char_t> literal(5000, 'a');
std::basic_string<char_t> buf;
buf += STR("<n><c>text</c><c>");
buf += literal;
buf += STR("</c></n>");
xml_document doc;
CHECK(doc.load_buffer_inplace(&buf[0], buf.size() * sizeof(char_t)));
xpath_query q(STR("string(n)"));
CHECK(q);
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, doc) == 1));
}
TEST(xpath_out_of_memory_evaluate_number_to_string)
{
test_runner::_memory_fail_threshold = 4096 + 128;
xpath_variable_set vars;
vars.set(STR("x"), 1e+308);
xpath_query q(STR("concat($x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x)"), &vars);
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
}
TEST(xpath_memory_concat_massive)
{
pugi::xml_document doc;
pugi::xml_node node = doc.append_child(STR("node"));
xml_document doc;
xml_node node = doc.append_child(STR("node"));
for (int i = 0; i < 5000; ++i)
node.append_child(STR("c")).text().set(i % 10);
pugi::xpath_query q(STR("/"));
xpath_query q(STR("/"));
size_t size = q.evaluate_string(0, 0, node);
CHECK(size == 5001);
}
TEST_XML(xpath_memory_translate_table, "<node>a</node>")
{
test_runner::_memory_fail_threshold = 32768 + 4096 + 128;
// 128b per table => we need 32+ translate calls to exhaust a page
std::basic_string<char_t> query = STR("concat(");
for (int i = 0; i < 64; ++i)
query += STR("translate(.,'a','A'),");
query += STR("'')");
CHECK_ALLOC_FAIL(CHECK(!xpath_query(query.c_str())));
}
TEST_XML(xpath_sort_copy_share, "<node><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2></node>")
{
// copy sharing shares the name/value data for nodes that can potentially make document order optimization invalid (silently)
@ -578,6 +756,17 @@ TEST(xpath_sort_crossdoc_different_depth)
CHECK((ns[0] == ns1[0] && ns[1] == ns2[0]) || (ns[0] == ns2[0] && ns[1] == ns1[0]));
}
TEST_XML(xpath_sort_empty_node, "<node><child1/><child2/></node>")
{
xml_node n = doc.child(STR("node"));
xpath_node nodes[] = { n.child(STR("child2")), xml_node(), n.child(STR("child1")), xml_node() };
xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
ns.sort();
CHECK(!ns[0] && !ns[1] && ns[2] == nodes[2] && ns[3] == nodes[0]);
}
TEST(xpath_allocate_string_out_of_memory)
{
std::basic_string<char_t> query;
@ -612,4 +801,15 @@ TEST(xpath_remove_duplicates)
tester % (2 + i);
}
}
TEST(xpath_anonymous_nodes)
{
xml_document doc;
doc.append_child(node_element);
doc.append_child(node_pi);
CHECK_XPATH_NODESET(doc, STR("/name"));
CHECK_XPATH_NODESET(doc, STR("/processing-instruction('a')"));
CHECK_XPATH_NODESET(doc, STR("/ns:*"));
}
#endif

View file

@ -2,13 +2,15 @@
#include <string.h> // because Borland's STL is braindead, we have to include <string.h> _before_ <string> in order to get memcmp
#include "common.hpp"
#include "test.hpp"
#include "helpers.hpp"
#include <string>
#include <vector>
using namespace pugi;
TEST_XML(xpath_api_select_nodes, "<node><head/><foo/><foo/><tail/></node>")
{
xpath_node_set ns1 = doc.select_nodes(STR("node/foo"));
@ -31,12 +33,12 @@ TEST_XML(xpath_api_select_node, "<node><head/><foo id='1'/><foo/><tail/></node>"
CHECK(n2.node().attribute(STR("id")).as_int() == 1);
xpath_node n3 = doc.select_node(STR("node/bar"));
CHECK(!n3);
xpath_node n4 = doc.select_node(STR("node/head/following-sibling::foo"));
xpath_node n5 = doc.select_node(STR("node/tail/preceding-sibling::foo"));
CHECK(n4.node().attribute(STR("id")).as_int() == 1);
CHECK(n5.node().attribute(STR("id")).as_int() == 1);
}
@ -107,6 +109,7 @@ TEST_XML(xpath_api_nodeset_accessors, "<node><foo/><foo/></node>")
TEST_XML(xpath_api_nodeset_copy, "<node><foo/><foo/></node>")
{
xpath_node_set empty;
xpath_node_set set = doc.select_nodes(STR("node/foo"));
xpath_node_set copy1 = set;
@ -120,7 +123,7 @@ TEST_XML(xpath_api_nodeset_copy, "<node><foo/><foo/></node>")
xpath_node_set copy3;
copy3 = set;
copy3 = copy3;
copy3 = xpath_node_set(copy3);
CHECK(copy3.size() == 2);
CHECK_STRING(copy3[0].node().name(), STR("foo"));
@ -132,7 +135,7 @@ TEST_XML(xpath_api_nodeset_copy, "<node><foo/><foo/></node>")
xpath_node_set copy5;
copy5 = set;
copy5 = xpath_node_set();
copy5 = empty;
CHECK(copy5.size() == 0);
}
@ -258,7 +261,7 @@ TEST(xpath_api_evaluate_string)
// test for just enough space
std::basic_string<char_t> s1 = base;
CHECK(q.evaluate_string(&s1[0], 11, xml_node()) == 11 && memcmp(&s1[0], STR("0123456789\0xxxxx"), 16 * sizeof(char_t)) == 0);
// test for just not enough space
std::basic_string<char_t> s2 = base;
CHECK(q.evaluate_string(&s2[0], 10, xml_node()) == 11 && memcmp(&s2[0], STR("012345678\0xxxxxx"), 16 * sizeof(char_t)) == 0);
@ -292,7 +295,7 @@ TEST(xpath_api_return_type)
TEST(xpath_api_query_bool)
{
xpath_query q(STR("node"));
CHECK(q);
CHECK((!q) == false);
}
@ -301,7 +304,7 @@ TEST(xpath_api_query_bool)
TEST(xpath_api_query_bool_fail)
{
xpath_query q(STR(""));
CHECK((q ? true : false) == false);
CHECK((!q) == true);
}
@ -398,17 +401,6 @@ TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "<node><a/><b/></node
CHECK(ns[0] == doc.child(STR("node")).child(STR("a")) && ns[1] == doc.child(STR("node")).child(STR("b")));
}
TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><foo/><tail/></node>")
{
xpath_node n1 = doc.select_single_node(STR("node/foo"));
xpath_query q(STR("node/foo"));
xpath_node n2 = doc.select_single_node(q);
CHECK(n1.node().attribute(STR("id")).as_int() == 1);
CHECK(n2.node().attribute(STR("id")).as_int() == 1);
}
TEST(xpath_api_empty)
{
xml_node c;
@ -418,7 +410,7 @@ TEST(xpath_api_empty)
CHECK(!q.evaluate_boolean(c));
}
#if __cplusplus >= 201103
#ifdef PUGIXML_HAS_MOVE
TEST_XML(xpath_api_nodeset_move_ctor, "<node><foo/><foo/><bar/></node>")
{
xpath_node_set set = doc.select_nodes(STR("node/bar/preceding::*"));
@ -572,6 +564,18 @@ TEST(xpath_api_nodeset_move_assign_empty)
CHECK(move.type() == xpath_node_set::type_sorted);
}
TEST_XML(xpath_api_nodeset_move_assign_self, "<node><foo/><foo/><bar/></node>")
{
xpath_node_set set = doc.select_nodes(STR("node/bar"));
CHECK(set.size() == 1);
CHECK(set.type() == xpath_node_set::type_sorted);
test_runner::_memory_fail_threshold = 1;
set = std::move(*&set);
}
TEST(xpath_api_query_move)
{
xml_node c;
@ -631,8 +635,8 @@ TEST(xpath_api_query_vector)
double result = 0;
for (auto& q: qv)
result += q.evaluate_number(xml_node());
for (size_t i = 0; i < qv.size(); ++i)
result += qv[i].evaluate_number(xml_node());
CHECK(result == 45);
}

View file

@ -1,12 +1,16 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
#include <string>
using namespace pugi;
TEST_XML(xpath_number_number, "<node>123</node>")
{
xml_node c;
xml_node n = doc.child(STR("node")).first_child();
// number with 0 arguments
CHECK_XPATH_NUMBER_NAN(c, STR("number()"));
CHECK_XPATH_NUMBER(n, STR("number()"), 123);
@ -35,7 +39,7 @@ TEST_XML(xpath_number_number, "<node>123</node>")
// number with 1 number argument
CHECK_XPATH_NUMBER(c, STR("number(1)"), 1);
// number with 2 arguments
CHECK_XPATH_FAIL(STR("number(1, 2)"));
}
@ -44,21 +48,21 @@ TEST_XML(xpath_number_sum, "<node>123<child>789</child></node><node/>")
{
xml_node c;
xml_node n = doc.child(STR("node"));
// sum with 0 arguments
CHECK_XPATH_FAIL(STR("sum()"));
// sum with 1 argument
CHECK_XPATH_NUMBER(c, STR("sum(.)"), 0);
CHECK_XPATH_NUMBER(n, STR("sum(.)"), 123789); // 123 .. 789
CHECK_XPATH_NUMBER(n, STR("sum(./descendant-or-self::node())"), 125490); // node + 123 + child + 789 = 123789 + 123 + 789 + 789 = 125490
CHECK_XPATH_NUMBER(n, STR("sum(.//node())"), 1701); // 123 + child + 789 = 123 + 789 + 789
CHECK_XPATH_NUMBER_NAN(doc.last_child(), STR("sum(.)"));
// sum with 2 arguments
CHECK_XPATH_FAIL(STR("sum(1, 2)"));
// sum with 1 non-node-set argument
CHECK_XPATH_FAIL(STR("sum(1)"));
}
@ -155,7 +159,7 @@ TEST(xpath_number_round)
TEST_XML(xpath_boolean_boolean, "<node />")
{
xml_node c;
// boolean with 0 arguments
CHECK_XPATH_FAIL(STR("boolean()"));
@ -182,14 +186,14 @@ TEST_XML(xpath_boolean_boolean, "<node />")
TEST(xpath_boolean_not)
{
xml_node c;
// not with 0 arguments
CHECK_XPATH_FAIL(STR("not()"));
// not with 1 argument
CHECK_XPATH_BOOLEAN(c, STR("not(true())"), false);
CHECK_XPATH_BOOLEAN(c, STR("not(false())"), true);
// boolean with 2 arguments
CHECK_XPATH_FAIL(STR("not(1, 2)"));
}
@ -197,7 +201,7 @@ TEST(xpath_boolean_not)
TEST(xpath_boolean_true)
{
xml_node c;
// true with 0 arguments
CHECK_XPATH_BOOLEAN(c, STR("true()"), true);
@ -208,7 +212,7 @@ TEST(xpath_boolean_true)
TEST(xpath_boolean_false)
{
xml_node c;
// false with 0 arguments
CHECK_XPATH_BOOLEAN(c, STR("false()"), false);
@ -219,7 +223,7 @@ TEST(xpath_boolean_false)
TEST_XML(xpath_boolean_lang, "<node xml:lang='en'><child xml:lang='zh-UK'><subchild attr=''/></child></node><foo><bar/></foo>")
{
xml_node c;
// lang with 0 arguments
CHECK_XPATH_FAIL(STR("lang()"));
@ -228,7 +232,7 @@ TEST_XML(xpath_boolean_lang, "<node xml:lang='en'><child xml:lang='zh-UK'><subch
CHECK_XPATH_BOOLEAN(doc.child(STR("foo")), STR("lang('en')"), false);
CHECK_XPATH_BOOLEAN(doc.child(STR("foo")), STR("lang('')"), false);
CHECK_XPATH_BOOLEAN(doc.child(STR("foo")).child(STR("bar")), STR("lang('en')"), false);
// lang with 1 argument, same language/prefix
CHECK_XPATH_BOOLEAN(doc.child(STR("node")), STR("lang('en')"), true);
CHECK_XPATH_BOOLEAN(doc.child(STR("node")).child(STR("child")), STR("lang('zh-uk')"), true);
@ -373,7 +377,7 @@ TEST(xpath_string_substring_before)
// substring-before with 1 argument
CHECK_XPATH_FAIL(STR("substring-before('a')"));
// substring-before with 2 arguments
CHECK_XPATH_STRING(c, STR("substring-before('abc', 'abc')"), STR(""));
CHECK_XPATH_STRING(c, STR("substring-before('abc', 'a')"), STR(""));
@ -382,7 +386,7 @@ TEST(xpath_string_substring_before)
CHECK_XPATH_STRING(c, STR("substring-before('abc', 'c')"), STR("ab"));
CHECK_XPATH_STRING(c, STR("substring-before('abc', '')"), STR(""));
CHECK_XPATH_STRING(c, STR("substring-before('', '')"), STR(""));
// substring-before with 2 arguments, from W3C standard
CHECK_XPATH_STRING(c, STR("substring-before(\"1999/04/01\",\"/\")"), STR("1999"));
@ -399,7 +403,7 @@ TEST(xpath_string_substring_after)
// substring-after with 1 argument
CHECK_XPATH_FAIL(STR("substring-after('a')"));
// substring-after with 2 arguments
CHECK_XPATH_STRING(c, STR("substring-after('abc', 'abc')"), STR(""));
CHECK_XPATH_STRING(c, STR("substring-after('abc', 'a')"), STR("bc"));
@ -430,10 +434,10 @@ TEST(xpath_string_substring)
// substring with 0 arguments
CHECK_XPATH_FAIL(STR("substring()"));
// substring with 1 argument
CHECK_XPATH_FAIL(STR("substring('')"));
// substring with 2 arguments
CHECK_XPATH_STRING(c, STR("substring('abcd', 2)"), STR("bcd"));
CHECK_XPATH_STRING(c, STR("substring('abcd', 1)"), STR("abcd"));
@ -517,7 +521,7 @@ TEST_XML_FLAGS(xpath_string_normalize_space, "<node> \t\r\rval1 \rval2\r\nval3\
// normalize-space with 0 arguments
CHECK_XPATH_STRING(c, STR("normalize-space()"), STR(""));
CHECK_XPATH_STRING(n, STR("normalize-space()"), STR("val1 val2 val3 val4"));
// normalize-space with 1 argument
CHECK_XPATH_STRING(c, STR("normalize-space('')"), STR(""));
CHECK_XPATH_STRING(c, STR("normalize-space('abcd')"), STR("abcd"));
@ -526,7 +530,7 @@ TEST_XML_FLAGS(xpath_string_normalize_space, "<node> \t\r\rval1 \rval2\r\nval3\
CHECK_XPATH_STRING(c, STR("normalize-space('ab\r\n\tcd')"), STR("ab cd"));
CHECK_XPATH_STRING(c, STR("normalize-space('ab cd')"), STR("ab cd"));
CHECK_XPATH_STRING(c, STR("normalize-space('\07')"), STR("\07"));
// normalize-space with 2 arguments
CHECK_XPATH_FAIL(STR("normalize-space(1, 2)"));
}
@ -537,13 +541,13 @@ TEST(xpath_string_translate)
// translate with 0 arguments
CHECK_XPATH_FAIL(STR("translate()"));
// translate with 1 argument
CHECK_XPATH_FAIL(STR("translate('a')"));
// translate with 2 arguments
CHECK_XPATH_FAIL(STR("translate('a', 'b')"));
// translate with 3 arguments
CHECK_XPATH_STRING(c, STR("translate('abc', '', '')"), STR("abc"));
CHECK_XPATH_STRING(c, STR("translate('abc', '', 'foo')"), STR("abc"));
@ -566,6 +570,7 @@ TEST(xpath_string_translate_table)
CHECK_XPATH_STRING(c, STR("translate('abcd\xe9 ', 'abc', 'ABC')"), STR("ABCd\xe9 "));
CHECK_XPATH_STRING(c, STR("translate('abcd\xe9 ', 'abc\xe9', 'ABC!')"), STR("ABCd! "));
CHECK_XPATH_STRING(c, STR("translate('abcd! ', 'abc!', 'ABC\xe9')"), STR("ABCd\xe9 "));
CHECK_XPATH_STRING(c, STR("translate('abcde', concat('abc', 'd'), 'ABCD')"), STR("ABCDe"));
CHECK_XPATH_STRING(c, STR("translate('abcde', 'abcd', concat('ABC', 'D'))"), STR("ABCDe"));
}
@ -604,7 +609,7 @@ TEST_XML(xpath_nodeset_position, "<node><c1/><c1/><c2/><c3/><c3/><c3/><c3/></nod
CHECK_XPATH_NODESET(n, STR("c1[position() = 3]"));
CHECK_XPATH_NODESET(n, STR("c2/preceding-sibling::node()[position() = 1]")) % 4;
CHECK_XPATH_NODESET(n, STR("c2/preceding-sibling::node()[position() = 2]")) % 3;
// position with 1 argument
CHECK_XPATH_FAIL(STR("position(c)"));
}
@ -640,7 +645,7 @@ TEST_XML(xpath_nodeset_id, "<node id='foo'/>")
// id with 0 arguments
CHECK_XPATH_FAIL(STR("id()"));
// id with 1 argument - no DTD => no id
CHECK_XPATH_NODESET(n, STR("id('foo')"));
@ -656,7 +661,7 @@ TEST_XML_FLAGS(xpath_nodeset_local_name, "<node xmlns:foo='http://foo'><c1>text<
// local-name with 0 arguments
CHECK_XPATH_STRING(c, STR("local-name()"), STR(""));
CHECK_XPATH_STRING(n, STR("local-name()"), STR("node"));
// local-name with 1 non-node-set argument
CHECK_XPATH_FAIL(STR("local-name(1)"));
@ -681,7 +686,7 @@ TEST_XML_FLAGS(xpath_nodeset_namespace_uri, "<node xmlns:foo='http://foo'><c1>te
// namespace-uri with 0 arguments
CHECK_XPATH_STRING(c, STR("namespace-uri()"), STR(""));
CHECK_XPATH_STRING(n.child(STR("c2")).child(STR("foo:child")), STR("namespace-uri()"), STR("http://foo2"));
// namespace-uri with 1 non-node-set argument
CHECK_XPATH_FAIL(STR("namespace-uri(1)"));
@ -710,7 +715,7 @@ TEST_XML_FLAGS(xpath_nodeset_name, "<node xmlns:foo='http://foo'><c1>text</c1><c
// name with 0 arguments
CHECK_XPATH_STRING(c, STR("name()"), STR(""));
CHECK_XPATH_STRING(n, STR("name()"), STR("node"));
// name with 1 non-node-set argument
CHECK_XPATH_FAIL(STR("name(1)"));
@ -733,7 +738,7 @@ TEST(xpath_function_arguments)
// conversion to string
CHECK_XPATH_NUMBER(c, STR("string-length(12)"), 2);
// conversion to number
CHECK_XPATH_NUMBER(c, STR("round('1.2')"), 1);
CHECK_XPATH_NUMBER(c, STR("round('1.7')"), 2);
@ -741,13 +746,13 @@ TEST(xpath_function_arguments)
// conversion to boolean
CHECK_XPATH_BOOLEAN(c, STR("not('1')"), false);
CHECK_XPATH_BOOLEAN(c, STR("not('')"), true);
// conversion to node set
CHECK_XPATH_FAIL(STR("sum(1)"));
// expression evaluation
CHECK_XPATH_NUMBER(c, STR("round((2 + 2 * 2) div 4)"), 2);
// empty expressions
CHECK_XPATH_FAIL(STR("round(,)"));
CHECK_XPATH_FAIL(STR("substring(,)"));
@ -799,4 +804,41 @@ TEST_XML(xpath_string_concat_translate, "<node>foobar</node>")
CHECK_XPATH_STRING(doc, STR("concat('a', 'b', 'c', translate(node, 'o', 'a'), 'd')"), STR("abcfaabard"));
}
TEST(xpath_unknown_functions)
{
char_t query[] = STR("a()");
for (char ch = 'a'; ch <= 'z'; ++ch)
{
query[0] = ch;
CHECK_XPATH_FAIL(query);
query[0] = char_t(ch - 32);
CHECK_XPATH_FAIL(query);
}
}
TEST(xpath_string_translate_table_out_of_memory)
{
xml_node c;
// our goal is to generate translate table OOM without generating query OOM
std::basic_string<char_t> query = STR("concat(");
size_t count = 20;
for (size_t i = 0; i < count; ++i)
{
if (i != 0) query += STR(",");
query += STR("translate('a','a','A')");
}
query += STR(")");
std::basic_string<char_t> result(count, 'A');
test_runner::_memory_fail_threshold = 5000;
CHECK_ALLOC_FAIL(CHECK_XPATH_STRING(c, query.c_str(), result.c_str()));
}
#endif

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST(xpath_operators_arithmetic)
{
@ -63,7 +65,7 @@ TEST(xpath_operators_arithmetic_specials)
CHECK_XPATH_STRING(c, STR("1 div 0 + 100"), STR("Infinity"));
CHECK_XPATH_STRING(c, STR("-1 div 0 + 100"), STR("-Infinity"));
CHECK_XPATH_STRING(c, STR("0 div 0 + 100"), STR("NaN"));
// unary - and multiplication clarifications from recommendations errata
CHECK_XPATH_STRING(c, STR("1 div -0"), STR("-Infinity"));
CHECK_XPATH_STRING(c, STR("-1 div -0"), STR("Infinity"));
@ -99,7 +101,7 @@ TEST(xpath_operators_logical)
CHECK_XPATH_BOOLEAN(c, STR("true() and false()"), false);
CHECK_XPATH_BOOLEAN(c, STR("false() and false()"), false);
CHECK_XPATH_BOOLEAN(c, STR("false() and true()"), false);
// boolean conversion
CHECK_XPATH_BOOLEAN(c, STR("1 or ''"), true);
CHECK_XPATH_BOOLEAN(c, STR("1 and ''"), false);
@ -192,7 +194,7 @@ TEST_XML(xpath_operators_equality_node_set_node_set, "<node><c1><v>a</v><v>b</v>
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c3/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c2/v != c3/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c4/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c5/v"), true); // (a, b) != (a, b), since a != b, as per XPath spec (comparison operators are so not intutive)
CHECK_XPATH_BOOLEAN(n, STR("c1/v != c5/v"), true); // (a, b) != (a, b), since a != b, as per XPath spec (comparison operators are so not intuitive)
CHECK_XPATH_BOOLEAN(n, STR("c3/v != c6/v"), false);
CHECK_XPATH_BOOLEAN(n, STR("c1/v != x"), false);
CHECK_XPATH_BOOLEAN(n, STR("x != c1/v"), false);
@ -225,7 +227,7 @@ TEST_XML(xpath_operators_equality_node_set_primitive, "<node><c1><v>1</v><v>-1</
CHECK_XPATH_BOOLEAN(n, STR("c2/v != 1"), true);
CHECK_XPATH_BOOLEAN(n, STR("1 != c2/v"), true);
#endif
// node set vs string
CHECK_XPATH_BOOLEAN(c, STR("x = '1'"), false);
CHECK_XPATH_BOOLEAN(c, STR("x != '1'"), false);
@ -332,11 +334,21 @@ TEST_XML(xpath_operators_inequality_node_set_node_set, "<node><c1><v>1</v><v>-1<
CHECK_XPATH_BOOLEAN(n, STR("c1/v < c3/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= c3/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v[1] > c1/v[1]"), false);
CHECK_XPATH_BOOLEAN(n, STR("c1/v[1] < c1/v[1]"), false);
CHECK_XPATH_BOOLEAN(n, STR("c1/v[1] >= c1/v[1]"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v[1] <= c1/v[1]"), true);
#ifndef MSVC6_NAN_BUG
CHECK_XPATH_BOOLEAN(n, STR("c1/v > c2/v"), false);
CHECK_XPATH_BOOLEAN(n, STR("c1/v >= c2/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v < c2/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c1/v <= c2/v"), true);
CHECK_XPATH_BOOLEAN(n, STR("c2/v[2] < c2/v[2]"), false);
CHECK_XPATH_BOOLEAN(n, STR("c2/v[2] > c2/v[2]"), false);
CHECK_XPATH_BOOLEAN(n, STR("c2/v[2] <= c2/v[2]"), false);
CHECK_XPATH_BOOLEAN(n, STR("c2/v[2] >= c2/v[2]"), false);
#endif
}
@ -423,6 +435,24 @@ TEST_XML(xpath_operators_union, "<node><employee/><employee secretary=''/><emplo
CHECK_XPATH_NODESET(n, STR(". | tail/preceding-sibling::employee | .")) % 2 % 3 % 4 % 6 % 8 % 11;
}
TEST_XML(xpath_operators_union_order, "<node />")
{
xml_node n = doc.child(STR("node"));
n.append_child(STR("c"));
n.prepend_child(STR("b"));
n.append_child(STR("d"));
n.prepend_child(STR("a"));
xpath_node_set ns = n.select_nodes(STR("d | d | b | c | b | a | c | d | b"));
CHECK(ns.size() == 4);
CHECK_STRING(ns[0].node().name(), STR("d"));
CHECK_STRING(ns[1].node().name(), STR("b"));
CHECK_STRING(ns[2].node().name(), STR("c"));
CHECK_STRING(ns[3].node().name(), STR("a"));
}
TEST(xpath_operators_union_error)
{
CHECK_XPATH_FAIL(STR(". | true()"));

View file

@ -1,9 +1,11 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
#include <string>
using namespace pugi;
TEST(xpath_literal_parse)
{
xml_node c;
@ -222,7 +224,7 @@ TEST(xpath_parse_paths_valid_unicode)
#if defined(PUGIXML_WCHAR_MODE)
xpath_query q(paths[i]);
#elif !defined(PUGIXML_NO_STL)
std::basic_string<char> path_utf8 = pugi::as_utf8(paths[i]);
std::basic_string<char> path_utf8 = as_utf8(paths[i]);
xpath_query q(path_utf8.c_str());
#endif
}
@ -274,7 +276,7 @@ TEST_XML(xpath_parse_absolute, "<div><s/></div>")
TEST(xpath_parse_out_of_memory_first_page)
{
test_runner::_memory_fail_threshold = 1;
test_runner::_memory_fail_threshold = 128;
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(STR("1")));
}
@ -293,6 +295,27 @@ TEST(xpath_parse_out_of_memory_string_to_number)
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(STR("0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")));
}
TEST(xpath_parse_out_of_memory_quoted_string)
{
test_runner::_memory_fail_threshold = 4096 + 128;
std::basic_string<char_t> literal(5000, 'a');
std::basic_string<char_t> query = STR("'") + literal + STR("'");
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(query.c_str()));
}
TEST(xpath_parse_out_of_memory_variable)
{
test_runner::_memory_fail_threshold = 4096 + 128;
std::basic_string<char_t> literal(5000, 'a');
std::basic_string<char_t> query = STR("$") + literal;
xpath_variable_set vars;
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL_VAR(query.c_str(), &vars));
}
TEST(xpath_parse_qname_error)
{
CHECK_XPATH_FAIL(STR("foo: bar"));
@ -313,4 +336,81 @@ TEST(xpath_parse_result_default)
CHECK(result.offset == 0);
}
TEST(xpath_parse_error_propagation)
{
char_t query[] = STR("(//foo[count(. | @*)] | ((a)//b)[1] | /foo | /foo/bar//more/ancestor-or-self::foobar | /text() | a[1 + 2 * 3 div (1+0) mod 2]//b[1]/c | a[$x])[true()]");
xpath_variable_set vars;
vars.set(STR("x"), 1.0);
xpath_query q(query, &vars);
CHECK(q);
for (size_t i = 0; i + 1 < sizeof(query) / sizeof(query[0]); ++i)
{
char_t ch = query[i];
query[i] = '%';
CHECK_XPATH_FAIL(query);
query[i] = ch;
}
}
TEST(xpath_parse_oom_propagation)
{
const char_t* query_base = STR("(//foo[count(. | @*)] | ((a)//b)[1] | /foo | /foo/bar//more/ancestor-or-self::foobar | /text() | a[1 + 2 * 3 div (1+0) mod 2]//b[1]/c | a[$x])[true()]");
xpath_variable_set vars;
vars.set(STR("x"), 1.0);
test_runner::_memory_fail_threshold = 4096 + 128;
{
xpath_query q(query_base, &vars);
CHECK(q);
}
for (size_t i = 3200; i < 4200; ++i)
{
std::basic_string<char_t> literal(i, 'a');
std::basic_string<char_t> query = STR("processing-instruction('") + literal + STR("') | ") + query_base;
CHECK_ALLOC_FAIL(CHECK_XPATH_FAIL(query.c_str()));
}
}
static std::basic_string<char_t> rep(const std::basic_string<char_t>& base, size_t count)
{
std::basic_string<char_t> result;
result.reserve(base.size() * count);
for (size_t i = 0; i < count; ++i)
result += base;
return result;
}
TEST(xpath_parse_depth_limit)
{
const size_t limit = 1500;
CHECK_XPATH_FAIL((rep(STR("("), limit) + STR("1") + rep(STR(")"), limit)).c_str());
CHECK_XPATH_FAIL((STR("(id('a'))") + rep(STR("[1]"), limit)).c_str());
CHECK_XPATH_FAIL((STR("/foo") + rep(STR("[1]"), limit)).c_str());
CHECK_XPATH_FAIL((STR("/foo") + rep(STR("/x"), limit)).c_str());
CHECK_XPATH_FAIL((STR("1") + rep(STR("+1"), limit)).c_str());
CHECK_XPATH_FAIL((STR("concat(") + rep(STR("1,"), limit) + STR("1)")).c_str());
CHECK_XPATH_FAIL((STR("/foo") + rep(STR("//x"), limit / 2)).c_str());
}
TEST_XML(xpath_parse_location_path, "<node><child/></node>")
{
CHECK_XPATH_NODESET(doc, STR("/node")) % 2;
CHECK_XPATH_NODESET(doc, STR("/@*"));
CHECK_XPATH_NODESET(doc, STR("/.")) % 1;
CHECK_XPATH_NODESET(doc, STR("/.."));
CHECK_XPATH_NODESET(doc, STR("/*")) % 2;
}
#endif

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_paths_axes_child, "<node attr='value'><child attr='value'><subchild/></child><another/><last/></node>")
{
@ -358,6 +360,13 @@ TEST_XML_FLAGS(xpath_paths_nodetest_principal, "<node attr='value'>pcdata<child/
CHECK_XPATH_NODESET(doc, STR("child::abra:*/attribute::abra:*/descendant-or-self::abra:*")); // attribute is not of element type
}
TEST_XML(xpath_paths_nodetest_attribute_namespace, "<node a1='v1' xmlns:x='?' />")
{
CHECK_XPATH_NODESET(doc, STR("node/attribute::node()")) % 3;
CHECK_XPATH_NODESET(doc, STR("node/attribute::xmlns:x"));
CHECK_XPATH_NODESET(doc, STR("node/attribute::xmlns:*"));
}
TEST_XML(xpath_paths_absolute, "<node attr='value'><foo><foo/><foo/></foo></node>")
{
xml_node c;
@ -696,4 +705,79 @@ TEST_XML(xpath_paths_null_nodeset_entries, "<node attr='value'/>")
CHECK(rs[0] == nodes[0]);
CHECK(rs[1] == nodes[2]);
}
TEST_XML(xpath_paths_step_leaf_coverage, "<n><n1/><n2 a='v'><child/></n2><n3/></n>")
{
xml_node n = doc.child(STR("n")).child(STR("n2"));
CHECK_XPATH_NODESET(n, STR("ancestor::node()")) % 2 % 1;
CHECK_XPATH_NODESET(n, STR("ancestor-or-self::node()")) % 4 % 2 % 1;
CHECK_XPATH_NODESET(n, STR("attribute::node()")) % 5;
CHECK_XPATH_NODESET(n, STR("child::node()")) % 6;
CHECK_XPATH_NODESET(n, STR("descendant::node()")) % 6;
CHECK_XPATH_NODESET(n, STR("descendant-or-self::node()")) % 4 % 6;
CHECK_XPATH_NODESET(n, STR("following::node()")) % 7;
CHECK_XPATH_NODESET(n, STR("following-sibling::node()")) % 7;
CHECK_XPATH_NODESET(n, STR("namespace::node()"));
CHECK_XPATH_NODESET(n, STR("parent::node()")) % 2;
CHECK_XPATH_NODESET(n, STR("preceding::node()")) % 3;
CHECK_XPATH_NODESET(n, STR("preceding-sibling::node()")) % 3;
CHECK_XPATH_NODESET(n, STR("self::node()")) % 4;
}
TEST_XML(xpath_paths_step_leaf_predicate_coverage, "<n><n1/><n2 a='v'><child/></n2><n3/></n>")
{
xml_node n = doc.child(STR("n")).child(STR("n2"));
CHECK_XPATH_NODESET(n, STR("ancestor::node()[1]")) % 2;
CHECK_XPATH_NODESET(n, STR("ancestor-or-self::node()[1]")) % 4;
CHECK_XPATH_NODESET(n, STR("attribute::node()[1]")) % 5;
CHECK_XPATH_NODESET(n, STR("child::node()[1]")) % 6;
CHECK_XPATH_NODESET(n, STR("descendant::node()[1]")) % 6;
CHECK_XPATH_NODESET(n, STR("descendant-or-self::node()[1]")) % 4;
CHECK_XPATH_NODESET(n, STR("following::node()[1]")) % 7;
CHECK_XPATH_NODESET(n, STR("following-sibling::node()[1]")) % 7;
CHECK_XPATH_NODESET(n, STR("namespace::node()[1]"));
CHECK_XPATH_NODESET(n, STR("parent::node()[1]")) % 2;
CHECK_XPATH_NODESET(n, STR("preceding::node()[1]")) % 3;
CHECK_XPATH_NODESET(n, STR("preceding-sibling::node()[1]")) % 3;
CHECK_XPATH_NODESET(n, STR("self::node()[1]")) % 4;
}
TEST_XML(xpath_paths_step_step_coverage, "<n><n1/><n2 a='v'><child/></n2><n3/></n>")
{
xml_node n = doc.child(STR("n")).child(STR("n2"));
CHECK_XPATH_NODESET(n, STR("./ancestor::node()")) % 2 % 1;
CHECK_XPATH_NODESET(n, STR("./ancestor-or-self::node()")) % 4 % 2 % 1;
CHECK_XPATH_NODESET(n, STR("./attribute::node()")) % 5;
CHECK_XPATH_NODESET(n, STR("./child::node()")) % 6;
CHECK_XPATH_NODESET(n, STR("./descendant::node()")) % 6;
CHECK_XPATH_NODESET(n, STR("./descendant-or-self::node()")) % 4 % 6;
CHECK_XPATH_NODESET(n, STR("./following::node()")) % 7;
CHECK_XPATH_NODESET(n, STR("./following-sibling::node()")) % 7;
CHECK_XPATH_NODESET(n, STR("./namespace::node()"));
CHECK_XPATH_NODESET(n, STR("./parent::node()")) % 2;
CHECK_XPATH_NODESET(n, STR("./preceding::node()")) % 3;
CHECK_XPATH_NODESET(n, STR("./preceding-sibling::node()")) % 3;
CHECK_XPATH_NODESET(n, STR("./self::node()")) % 4;
}
TEST_XML(xpath_paths_step_step_predicate_coverage, "<n><n1/><n2 a='v'><child/></n2><n3/></n>")
{
xml_node n = doc.child(STR("n")).child(STR("n2"));
CHECK_XPATH_NODESET(n, STR("./ancestor::node()[1]")) % 2;
CHECK_XPATH_NODESET(n, STR("./ancestor-or-self::node()[1]")) % 4;
CHECK_XPATH_NODESET(n, STR("./attribute::node()[1]")) % 5;
CHECK_XPATH_NODESET(n, STR("./child::node()[1]")) % 6;
CHECK_XPATH_NODESET(n, STR("./descendant::node()[1]")) % 6;
CHECK_XPATH_NODESET(n, STR("./descendant-or-self::node()[1]")) % 4;
CHECK_XPATH_NODESET(n, STR("./following::node()[1]")) % 7;
CHECK_XPATH_NODESET(n, STR("./following-sibling::node()[1]")) % 7;
CHECK_XPATH_NODESET(n, STR("./namespace::node()[1]"));
CHECK_XPATH_NODESET(n, STR("./parent::node()[1]")) % 2;
CHECK_XPATH_NODESET(n, STR("./preceding::node()[1]")) % 3;
CHECK_XPATH_NODESET(n, STR("./preceding-sibling::node()[1]")) % 3;
CHECK_XPATH_NODESET(n, STR("./self::node()[1]")) % 4;
}
#endif

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_paths_abbrev_w3c_1, "<node><para/><foo/><para/></node>")
{

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_paths_w3c_1, "<node><para/><foo/><para/></node>")
{

View file

@ -1,9 +1,11 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
#include <string>
using namespace pugi;
TEST(xpath_variables_type_none)
{
xpath_variable_set set;
@ -261,7 +263,7 @@ TEST(xpath_variables_multiple_documents)
CHECK(ns.size() == 3);
CHECK(ns[0] != ns[1] && ns[0] != ns[2]);
xml_node n0 = doc.child(STR("node")), n1 = doc1.child(STR("node")), n2 = doc2.child(STR("node"));
CHECK(n0 == ns[0].node() || n0 == ns[1].node() || n0 == ns[2].node());
@ -302,7 +304,23 @@ TEST_XML(xpath_variables_select, "<node attr='1'/><node attr='2'/>")
TEST(xpath_variables_empty_name)
{
xpath_variable_set set;
CHECK(!set.add(STR(""), xpath_type_node_set));
CHECK(!set.add(STR(""), xpath_type_number));
CHECK(!set.add(STR(""), xpath_type_string));
CHECK(!set.add(STR(""), xpath_type_boolean));
}
TEST(xpath_variables_long_name_out_of_memory_add)
{
std::basic_string<char_t> name(1000, 'a');
test_runner::_memory_fail_threshold = 1000;
xpath_variable_set set;
CHECK_ALLOC_FAIL(CHECK(!set.add(name.c_str(), xpath_type_node_set)));
CHECK_ALLOC_FAIL(CHECK(!set.add(name.c_str(), xpath_type_number)));
CHECK_ALLOC_FAIL(CHECK(!set.add(name.c_str(), xpath_type_string)));
CHECK_ALLOC_FAIL(CHECK(!set.add(name.c_str(), xpath_type_boolean)));
}
TEST_XML(xpath_variables_inside_filter, "<node key='1' value='2'/><node key='2' value='1'/><node key='1' value='1'/>")
@ -436,7 +454,7 @@ TEST_XML(xpath_variables_copy, "<node />")
CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
set3 = set3;
set3 = xpath_variable_set(set3);
CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
@ -474,7 +492,19 @@ TEST_XML(xpath_variables_copy_out_of_memory, "<node1 /><node2 />")
CHECK(set2.get(STR("d"))->get_node_set().size() == 2);
}
#if __cplusplus >= 201103
TEST(xpath_variables_copy_out_of_memory_clone)
{
xpath_variable_set set1;
set1.set(STR("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), true);
xpath_variable_set set2 = set1;
test_runner::_memory_fail_threshold = 60;
CHECK_ALLOC_FAIL(xpath_variable_set set3 = set1);
}
#ifdef PUGIXML_HAS_MOVE
TEST_XML(xpath_variables_move, "<node />")
{
xpath_variable_set set;
@ -579,4 +609,65 @@ TEST(xpath_variables_copy_big_out_of_memory)
CHECK(!copy.get(name));
}
}
TEST(xpath_variables_copy_big_value_out_of_memory)
{
xpath_variable_set set;
std::basic_string<char_t> var(10000, 'a');
set.set(STR("x"), var.c_str());
test_runner::_memory_fail_threshold = 15000;
xpath_variable_set copy;
CHECK_ALLOC_FAIL(copy = set);
CHECK(!copy.get(STR("x")));
}
TEST_XML(xpath_variables_evaluate_node_set_out_of_memory, "<node />")
{
for (size_t i = 0; i < 600; ++i)
doc.append_child(STR("node"));
xpath_node_set ns = doc.select_nodes(STR("node"));
CHECK(ns.size() == 601);
xpath_variable_set set;
set.set(STR("nodes"), ns);
xpath_query q(STR("$nodes"), &set);
test_runner::_memory_fail_threshold = 1;
CHECK_ALLOC_FAIL(q.evaluate_node_set(xml_node()).empty());
}
TEST_XML(xpath_variables_type_conversion, "<node>15</node>")
{
xpath_variable_set set;
set.set(STR("a"), true);
set.set(STR("b"), 42.0);
set.set(STR("c"), STR("test"));
set.set(STR("d"), doc.select_nodes(STR("node")));
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("boolean($a) = true()"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("number($a) = 1"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("string($a) = 'true'"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("boolean($b) = true()"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("number($b) = 42"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("string($b) = '42'"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("boolean($c) = true()"), &set, true);
#ifndef MSVC6_NAN_BUG
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("number($c) = 0"), &set, false);
#endif
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("string($c) = 'test'"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("boolean($d) = true()"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("number($d) = 15"), &set, true);
CHECK_XPATH_BOOLEAN_VAR(xml_node(), STR("string($d) = '15'"), &set, true);
}
#endif

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST(xpath_xalan_boolean_1)
{
@ -363,7 +365,7 @@ TEST_XML(xpath_xalan_math_8, "<k>0.0004</k>")
CHECK_XPATH_NUMBER(doc, STR("number(4 div 10000)"), 0.0004);
// +0 works around extended precision in div on x86 (this is needed for some configurations in MinGW 3.4)
CHECK_XPATH_BOOLEAN(doc, STR("(number(k) = (4 div 10000 + 0))"), true);
CHECK_XPATH_BOOLEAN(doc, STR("(number(k) = (4 div 10000 + 0))"), true);
CHECK_XPATH_NUMBER(doc, STR("number(0.0001 * 4)"), 0.0004);
CHECK_XPATH_BOOLEAN(doc, STR("(number(k) = (0.0001 * 4))"), true);
}

View file

@ -2,11 +2,13 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
#include <string>
#include <algorithm>
using namespace pugi;
TEST_XML(xpath_xalan_string_1, "<doc a='test'>ENCYCLOPEDIA</doc>")
{
xml_node c;

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_xalan_axes_1, "<far-north><north-north-west1/><north-north-west2/><north><near-north><far-west/><west/><near-west/><center center-attr-1='c1' center-attr-2='c2' center-attr-3='c3'><near-south-west/><near-south><south><far-south/></south></near-south><near-south-east/></center><near-east/><east/><far-east/></near-north></north><north-north-east1/><north-north-east2/></far-north>")
{

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_xalan_position_1, "<doc><a>1</a><a>2</a><a>3</a><a>4</a></doc>")
{

View file

@ -1,6 +1,8 @@
#ifndef PUGIXML_NO_XPATH
#include "common.hpp"
#include "test.hpp"
using namespace pugi;
TEST_XML(xpath_xalan_select_1, "<doc><a><b attr='test'/></a><c><d><e/></d></c></doc>")
{

View file

@ -8,8 +8,8 @@
struct xml_writer_string: public pugi::xml_writer
{
std::string contents;
virtual void write(const void* data, size_t size);
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
std::string as_narrow() const;
std::basic_string<wchar_t> as_wide() const;