Compare commits
4 commits
master
...
clang-form
Author | SHA1 | Date | |
---|---|---|---|
|
c237489a6c | ||
|
3c75d4d612 | ||
|
e61dbc5e88 | ||
|
7d6901bff2 |
77 changed files with 17417 additions and 19106 deletions
12
.clang-format
Normal file
12
.clang-format
Normal file
|
@ -0,0 +1,12 @@
|
|||
Standard: Cpp03
|
||||
UseTab: ForIndentation
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
BreakBeforeBraces: Allman
|
||||
IndentCaseLabels: false
|
||||
ColumnLimit: 0
|
||||
PointerAlignment: Left
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
NamespaceIndentation: None
|
||||
AlignEscapedNewlines: DontAlign
|
|
@ -1,7 +1,2 @@
|
|||
comment: false
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
patch: off
|
||||
|
||||
|
|
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
8
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
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
5
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,5 +0,0 @@
|
|||
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.
|
8
.github/ISSUE_TEMPLATE/feature_request.md
vendored
8
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
52
.github/workflows/build.yml
vendored
52
.github/workflows/build.yml
vendored
|
@ -1,52 +0,0 @@
|
|||
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
|
26
.travis.yml
Normal file
26
.travis.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
language: cpp
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
|
||||
env:
|
||||
- DEFINES=standard
|
||||
- DEFINES=PUGIXML_WCHAR_MODE
|
||||
- DEFINES=PUGIXML_COMPACT
|
||||
- DEFINES=PUGIXML_NO_EXCEPTIONS
|
||||
script:
|
||||
- make test cxxstd=c++11 defines=$DEFINES config=coverage -j2
|
||||
- make test cxxstd=c++11 defines=$DEFINES config=release -j2
|
||||
- make test cxxstd=c++98 defines=$DEFINES config=debug -j2
|
||||
|
||||
after_success:
|
||||
- sed -e "s/#####\(.*\)\(\/\/ unreachable.*\)/ 1\1\2/" -i pugixml.cpp.gcov
|
||||
- bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov
|
310
CMakeLists.txt
310
CMakeLists.txt
|
@ -1,263 +1,89 @@
|
|||
cmake_minimum_required(VERSION 3.4)
|
||||
project(pugixml VERSION 1.13 LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
project(pugixml VERSION 1.9)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
|
||||
option(BUILD_TESTS "Build tests" OFF)
|
||||
option(USE_VERSIONED_LIBDIR "Use a private subdirectory to install the headers and libs" OFF)
|
||||
option(USE_POSTFIX "Use separate postfix for each configuration to make sure you can install multiple build outputs" OFF)
|
||||
|
||||
set(BUILD_DEFINES "" CACHE STRING "Build defines")
|
||||
|
||||
if(MSVC)
|
||||
option(STATIC_CRT "Use static CRT libraries" OFF)
|
||||
|
||||
# Rewrite command line flags to use /MT if necessary
|
||||
if(STATIC_CRT)
|
||||
foreach(flag_var
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if(${flag_var} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endif(${flag_var} MATCHES "/MD")
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Pre-defines standard install locations on *nix systems.
|
||||
include(GNUInstallDirs)
|
||||
include(CTest)
|
||||
mark_as_advanced(CLEAR CMAKE_INSTALL_LIBDIR CMAKE_INSTALL_INCLUDEDIR)
|
||||
|
||||
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)
|
||||
set(HEADERS src/pugixml.hpp src/pugiconfig.hpp)
|
||||
set(SOURCES src/pugixml.cpp)
|
||||
|
||||
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
|
||||
if(DEFINED BUILD_DEFINES)
|
||||
foreach(DEFINE ${BUILD_DEFINES})
|
||||
add_definitions("-D" ${DEFINE})
|
||||
endforeach()
|
||||
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)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
add_library(pugixml SHARED ${HEADERS} ${SOURCES})
|
||||
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()
|
||||
add_library(pugixml STATIC ${HEADERS} ${SOURCES})
|
||||
endif()
|
||||
|
||||
configure_file(scripts/pugixml.pc.in pugixml.pc @ONLY)
|
||||
|
||||
if (NOT DEFINED PUGIXML_RUNTIME_COMPONENT)
|
||||
set(PUGIXML_RUNTIME_COMPONENT Runtime)
|
||||
# Export symbols for shared library builds
|
||||
if(BUILD_SHARED_LIBS AND MSVC)
|
||||
target_compile_definitions(pugixml PRIVATE "PUGIXML_API=__declspec(dllexport)")
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED PUGIXML_LIBRARY_COMPONENT)
|
||||
set(PUGIXML_LIBRARY_COMPONENT Library)
|
||||
# Enable C++11 long long for compilers that are capable of it
|
||||
if(NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} STRLESS 3.1 AND ";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_long_long_type;")
|
||||
target_compile_features(pugixml PUBLIC cxx_long_long_type)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED PUGIXML_DEVELOPMENT_COMPONENT)
|
||||
set(PUGIXML_DEVELOPMENT_COMPONENT Development)
|
||||
set_target_properties(pugixml PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
if(USE_VERSIONED_LIBDIR)
|
||||
# Install library into its own directory under LIBDIR
|
||||
set(INSTALL_SUFFIX /pugixml-${pugixml_VERSION})
|
||||
endif()
|
||||
|
||||
set(namelink-component)
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.12)
|
||||
set(namelink-component NAMELINK_COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
target_include_directories(pugixml PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}${INSTALL_SUFFIX}>)
|
||||
|
||||
if(USE_POSTFIX AND CMAKE_CONFIGURATION_TYPES)
|
||||
set_target_properties(pugixml PROPERTIES DEBUG_POSTFIX "_d" MINSIZEREL_POSTFIX "_m" RELWITHDEBINFO_POSTFIX "_r")
|
||||
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})
|
||||
install(TARGETS pugixml EXPORT pugixml-config
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${INSTALL_SUFFIX}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${INSTALL_SUFFIX}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${INSTALL_SUFFIX})
|
||||
install(EXPORT pugixml-config DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml)
|
||||
|
||||
export(EXPORT pugixml-targets
|
||||
NAMESPACE pugixml::)
|
||||
configure_file(scripts/pugixml.pc.in ${PROJECT_BINARY_DIR}/pugixml.pc @ONLY)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
|
||||
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})
|
||||
if(BUILD_TESTS)
|
||||
file(GLOB TEST_SOURCES tests/*.cpp)
|
||||
file(GLOB FUZZ_SOURCES tests/fuzz_*.cpp)
|
||||
list(REMOVE_ITEM TEST_SOURCES ${FUZZ_SOURCES})
|
||||
|
||||
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)
|
||||
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()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2018 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
|
12
Makefile
12
Makefile
|
@ -12,9 +12,9 @@ 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=$(filter-out scripts/archive.py docs/%.adoc,$(shell git ls-files docs scripts src CMakeLists.txt LICENSE.md readme.txt))
|
||||
RELEASE=$(filter-out scripts/archive.py docs/%.adoc,$(shell git ls-files contrib docs scripts src CMakeLists.txt readme.txt))
|
||||
|
||||
CXXFLAGS=-g -Wall -Wextra -Werror -pedantic -Wundef -Wshadow -Wcast-align -Wcast-qual -Wold-style-cast -Wdouble-promotion
|
||||
CXXFLAGS=-g -Wall -Wextra -Werror -pedantic -Wundef -Wshadow -Wcast-align -Wcast-qual -Wold-style-cast
|
||||
LDFLAGS=
|
||||
|
||||
ifeq ($(config),release)
|
||||
|
@ -27,7 +27,7 @@ ifeq ($(config),coverage)
|
|||
endif
|
||||
|
||||
ifeq ($(config),sanitize)
|
||||
CXXFLAGS+=-fsanitize=address,undefined -fno-sanitize=float-divide-by-zero,float-cast-overflow -fno-sanitize-recover=all
|
||||
CXXFLAGS+=-fsanitize=address,undefined
|
||||
LDFLAGS+=-fsanitize=address,undefined
|
||||
endif
|
||||
|
||||
|
@ -58,7 +58,6 @@ 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)
|
||||
|
@ -75,9 +74,12 @@ release: build/pugixml-$(VERSION).tar.gz build/pugixml-$(VERSION).zip
|
|||
|
||||
docs: docs/quickstart.html docs/manual.html
|
||||
|
||||
format:
|
||||
clang-format -i src/*.cpp src/*.hpp tests/*.cpp tests/*.hpp
|
||||
|
||||
build/pugixml-%: .FORCE | $(RELEASE)
|
||||
@mkdir -p $(BUILD)
|
||||
TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python3 scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
|
||||
TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $|
|
||||
|
||||
$(EXECUTABLE): $(OBJECTS)
|
||||
$(CXX) $(OBJECTS) $(LDFLAGS) -o $@
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pugixml [](https://github.com/zeux/pugixml/actions) [](https://ci.appveyor.com/project/zeux/pugixml) [](https://codecov.io/github/zeux/pugixml?branch=master) 
|
||||
pugixml [](https://travis-ci.org/zeux/pugixml) [](https://ci.appveyor.com/project/zeux/pugixml) [](https://codecov.io/github/zeux/pugixml?branch=master) 
|
||||
=======
|
||||
|
||||
pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# 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).
|
14
appveyor.yml
14
appveyor.yml
|
@ -1,25 +1,15 @@
|
|||
image:
|
||||
- Visual Studio 2022
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2015
|
||||
- Visual Studio 2017
|
||||
|
||||
version: "{branch}-{build}"
|
||||
|
||||
build_script:
|
||||
- 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}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\scripts\nuget_build.ps1 }
|
||||
|
||||
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
|
||||
|
|
63
contrib/foreach.hpp
Normal file
63
contrib/foreach.hpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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
|
|
@ -1,7 +1,7 @@
|
|||
website <https://pugixml.org>; repository <https://github.com/zeux/pugixml>
|
||||
website <http://pugixml.org>; repository <http://github.com/zeux/pugixml>
|
||||
:toc: right
|
||||
:source-highlighter: pygments
|
||||
:source-language: c++
|
||||
:sectanchors:
|
||||
:sectlinks:
|
||||
:imagesdir: images
|
||||
:imagesdir: images
|
172
docs/manual.adoc
172
docs/manual.adoc
|
@ -8,7 +8,7 @@ include::config.adoc[]
|
|||
[[overview.introduction]]
|
||||
=== Introduction
|
||||
|
||||
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,XPath 1.0 implementation>> for complex data-driven tree queries. Full Unicode support is also available, with <<dom.unicode,two Unicode interface variants>> and conversions between different Unicode encodings (which happen automatically during parsing/saving). The library is <<install.portability,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 <<overview.license,MIT license>>, making it completely free to use in both open-source and proprietary applications.
|
||||
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,XPath 1.0 implementation>> for complex data-driven tree queries. Full Unicode support is also available, with <<dom.unicode,two Unicode interface variants>> and conversions between different Unicode encodings (which happen automatically during parsing/saving). The library is <<install.portability,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 <<overview.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 or XML Schema validation, the library is not for you.
|
||||
|
||||
|
@ -46,7 +46,7 @@ Thanks to *Vyacheslav Egorov* for documentation proofreading and fuzz testing.
|
|||
The pugixml library is distributed under the MIT license:
|
||||
|
||||
....
|
||||
Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2018 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
@ -73,8 +73,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-2018 Arseny Kapoulkine.
|
||||
....
|
||||
|
||||
[[install]]
|
||||
|
@ -148,7 +148,7 @@ The complete pugixml source consists of three files - one source file, `pugixml.
|
|||
[[install.building.embed]]
|
||||
==== Building pugixml as a part of another static library/executable
|
||||
|
||||
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*.
|
||||
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.
|
||||
|
||||
If you're using Microsoft Visual Studio and the project has precompiled headers turned on, you'll see the following error messages:
|
||||
|
||||
|
@ -270,7 +270,7 @@ The XML document is represented with a tree data structure. The root of the tree
|
|||
[[xml_node_type]]
|
||||
The tree nodes can be of one of the following types (which together form the enumeration `xml_node_type`):
|
||||
|
||||
* Document node ([[node_document]]`node_document`) - this is the root of the tree, which consists of several child nodes. This node corresponds to <<xml_document,xml_document>> class; note that <<xml_document,xml_document>> is a sub-class of <<xml_node,xml_node>>, so the entire node interface is also available. However, document node is special in several ways, which are covered below. There can be only one document node in the tree; document node does not have any XML representation. Document generally has one child element node (see [[xml_document::document_element]]`document_element()`), although documents parsed from XML fragments (see [[parse_fragment]]`parse_fragment`) can have more than one.
|
||||
* Document node ([[node_document]]`node_document`) - this is the root of the tree, which consists of several child nodes. This node corresponds to <<xml_document,xml_document>> class; note that <<xml_document,xml_document>> is a sub-class of <<xml_node,xml_node>>, so the entire node interface is also available. However, document node is special in several ways, which are covered below. There can be only one document node in the tree; document node does not have any XML representation.
|
||||
|
||||
* Element/tag node ([[node_element]]`node_element`) - this is the most common type of node, which represents XML elements. Element nodes have a name, a collection of attributes and a collection of child nodes (both of which may be empty). The attribute is a simple name/value pair. The example XML representation of element nodes is as follows:
|
||||
+
|
||||
|
@ -380,7 +380,7 @@ There is a special value of `xml_node` type, known as null node or empty node (s
|
|||
Both `xml_node` and `xml_attribute` have the default constructor which initializes them to null objects.
|
||||
|
||||
[[xml_attribute::comparison]][[xml_node::comparison]]
|
||||
`xml_node` and `xml_attribute` try to behave like pointers, that is, they can be compared with other objects of the same type, making it possible to use them as keys in associative containers. All handles to the same underlying object are equal, and any two handles to different underlying objects are not equal. Null handles only compare as equal to null handles. The result of relational comparison can not be reliably determined from the order of nodes in file or in any other way. Do not use relational comparison operators except for search optimization (i.e. associative container keys).
|
||||
`xml_node` and `xml_attribute` try to behave like pointers, that is, they can be compared with other objects of the same type, making it possible to use them as keys in associative containers. All handles to the same underlying object are equal, and any two handles to different underlying objects are not equal. Null handles only compare as equal to themselves. The result of relational comparison can not be reliably determined from the order of nodes in file or in any other way. Do not use relational comparison operators except for search optimization (i.e. associative container keys).
|
||||
|
||||
[[xml_attribute::hash_value]][[xml_node::hash_value]]
|
||||
If you want to use `xml_node` or `xml_attribute` objects as keys in hash-based associative containers, you can use the `hash_value` member functions. They return the hash values that are guaranteed to be the same for all handles to the same underlying object. The hash value for null handles is 0. Note that hash value does not depend on the content of the node, only on the location of the underlying structure in memory - this means that loading the same document twice will likely produce different hash values, and copying the node will not preserve the hash.
|
||||
|
@ -749,7 +749,7 @@ These flags control the resulting tree contents:
|
|||
* [[parse_embed_pcdata]]`parse_embed_pcdata` determines if PCDATA contents is to be saved as element values. Normally element nodes have names but not values; this flag forces the parser to store the contents as a value if PCDATA is the first child of the element node (otherwise PCDATA node is created as usual). This can significantly reduce the memory required for documents with many PCDATA nodes. To retrieve the data you can use `xml_node::value()` on the element nodes or any of the higher-level functions like `child_value` or `text`. This flag is *off* by default.
|
||||
Since this flag significantly changes the DOM structure it is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. This flag is *off* by default.
|
||||
|
||||
* [[parse_fragment]]`parse_fragment` determines if document should be treated as a fragment of a valid XML. Parsing document as a fragment leads to top-level PCDATA content (i.e. text that is not located inside a node) to be added to a tree, and additionally treats documents without element nodes as valid and permits multiple top-level element nodes. This flag is *off* by default.
|
||||
* [[parse_fragment]]`parse_fragment` determines if document should be treated as a fragment of a valid XML. Parsing document as a fragment leads to top-level PCDATA content (i.e. text that is not located inside a node) to be added to a tree, and additionally treats documents without element nodes as valid. This flag is *off* by default.
|
||||
|
||||
CAUTION: Using in-place parsing (<<xml_document::load_buffer_inplace,load_buffer_inplace>>) with `parse_fragment` flag may result in the loss of the last character of the buffer if it is a part of PCDATA. Since PCDATA values are null-terminated strings, the only way to resolve this is to provide a null-terminated buffer as an input to `load_buffer_inplace` - i.e. `doc.load_buffer_inplace("test\0", 5, pugi::parse_default | pugi::parse_fragment)`.
|
||||
|
||||
|
@ -818,7 +818,6 @@ As for rejecting invalid XML documents, there are a number of incompatibilities
|
|||
* XML data is not required to begin with document declaration; additionally, document declaration can appear after comments and other nodes.
|
||||
* Invalid document type declarations are silently ignored in some cases.
|
||||
* Unicode validation is not performed so invalid UTF sequences are not rejected.
|
||||
* Document can contain multiple top-level element nodes.
|
||||
|
||||
[[access]]
|
||||
== Accessing document data
|
||||
|
@ -969,28 +968,6 @@ xml_node xml_node::previous_sibling(const char_t* name) const;
|
|||
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
|
||||
----
|
||||
|
||||
[[xml_node::attribute_hinted]]
|
||||
`attribute` function needs to look for the target attribute by name. If a node has many attributes, finding each by name can be time consuming. If you have an idea of how attributes are ordered in the node, you can use a faster function:
|
||||
|
||||
[source]
|
||||
----
|
||||
xml_attribute xml_node::attribute(const char_t* name, xml_attribute& hint) const;
|
||||
----
|
||||
|
||||
The extra `hint` argument is used to guess where the attribute might be, and is updated to the location of the next attribute so that if you search for multiple attributes in the right order, the performance is maximized. Note that `hint` has to be either null or has to belong to the node, otherwise the behavior is undefined.
|
||||
|
||||
You can use this function as follows:
|
||||
|
||||
[source]
|
||||
----
|
||||
xml_attribute hint;
|
||||
xml_attribute id = node.attribute("id", hint);
|
||||
xml_attribute name = node.attribute("name", hint);
|
||||
xml_attribute version = node.attribute("version", hint);
|
||||
----
|
||||
|
||||
This code is correct regardless of the order of the attributes, but it's faster if `"id"`, `"name"` and `"version"` occur in that order.
|
||||
|
||||
[[xml_node::find_child_by_attribute]]
|
||||
Occasionally the needed node is specified not by the unique name but instead by the value of some attribute; for example, it is common to have node collections with each node having a unique id: `<group><item id="1"/> <item id="2"/></group>`. There are two functions for finding child nodes based on the attribute values:
|
||||
|
||||
|
@ -1276,7 +1253,6 @@ As discussed before, nodes can have name and value, both of which are strings. D
|
|||
----
|
||||
bool xml_node::set_name(const char_t* rhs);
|
||||
bool xml_node::set_value(const char_t* rhs);
|
||||
bool xml_node::set_value(const char_t* rhs, size_t size);
|
||||
----
|
||||
|
||||
Both functions try to set the name/value to the specified string, and return the operation result. The operation fails if the node can not have name or value (for instance, when trying to call `set_name` on a <<node_pcdata,node_pcdata>> node), if the node handle is null, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to these functions). The name/value content is not verified, so take care to use only valid XML names, or the document may become malformed.
|
||||
|
@ -1298,7 +1274,6 @@ All attributes have name and value, both of which are strings (value may be empt
|
|||
----
|
||||
bool xml_attribute::set_name(const char_t* rhs);
|
||||
bool xml_attribute::set_value(const char_t* rhs);
|
||||
bool xml_attribute::set_value(const char_t* rhs, size_t size);
|
||||
----
|
||||
|
||||
Both functions try to set the name/value to the specified string, and return the operation result. The operation fails if the attribute handle is null, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to these functions). The name/value content is not verified, so take care to use only valid XML names, or the document may become malformed.
|
||||
|
@ -1312,9 +1287,7 @@ bool xml_attribute::set_value(unsigned int rhs);
|
|||
bool xml_attribute::set_value(long rhs);
|
||||
bool xml_attribute::set_value(unsigned long rhs);
|
||||
bool xml_attribute::set_value(double rhs);
|
||||
bool xml_attribute::set_value(double rhs, int precision);
|
||||
bool xml_attribute::set_value(float rhs);
|
||||
bool xml_attribute::set_value(float rhs, int precision);
|
||||
bool xml_attribute::set_value(bool rhs);
|
||||
bool xml_attribute::set_value(long long rhs);
|
||||
bool xml_attribute::set_value(unsigned long long rhs);
|
||||
|
@ -1405,18 +1378,16 @@ include::samples/modify_add.cpp[tags=code]
|
|||
[[modify.remove]]
|
||||
=== Removing nodes/attributes
|
||||
|
||||
[[xml_node::remove_attribute]][[xml_node::remove_attributes]][[xml_node::remove_child]][[xml_node::remove_children]]
|
||||
[[xml_node::remove_attribute]][[xml_node::remove_child]]
|
||||
If you do not want your document to contain some node or attribute, you can remove it with one of the following functions:
|
||||
|
||||
[source]
|
||||
----
|
||||
bool xml_node::remove_attribute(const xml_attribute& a);
|
||||
bool xml_node::remove_attributes();
|
||||
bool xml_node::remove_child(const xml_node& n);
|
||||
bool xml_node::remove_children();
|
||||
----
|
||||
|
||||
`remove_attribute` removes the attribute from the attribute list of the node, and returns the operation result. `remove_child` removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. `remove_attributes` removes all the attributes of the node, and returns the operation result. `remove_children` removes all the child nodes of the node, and returns the operation result. Removing fails if one of the following is true:
|
||||
`remove_attribute` removes the attribute from the attribute list of the node, and returns the operation result. `remove_child` removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. Removing fails if one of the following is true:
|
||||
|
||||
* The node the function is called on is null;
|
||||
* The attribute/node to be removed is null;
|
||||
|
@ -1452,7 +1423,6 @@ Once you have an `xml_text` object, you can set the text contents using the foll
|
|||
[source]
|
||||
----
|
||||
bool xml_text::set(const char_t* rhs);
|
||||
bool xml_text::set(const char_t* rhs, size_t size);
|
||||
----
|
||||
|
||||
This function tries to set the contents to the specified string, and returns the operation result. The operation fails if the text object was retrieved from a node that can not have a value and is not an element node (i.e. it is a <<node_declaration,node_declaration>> node), if the text object is empty, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to this function). Note that if the text object was retrieved from an element node, this function creates the PCDATA child node if necessary (i.e. if the element node does not have a PCDATA/CDATA child already).
|
||||
|
@ -1467,9 +1437,7 @@ bool xml_text::set(unsigned int rhs);
|
|||
bool xml_text::set(long rhs);
|
||||
bool xml_text::set(unsigned long rhs);
|
||||
bool xml_text::set(double rhs);
|
||||
bool xml_text::set(double rhs, int precision);
|
||||
bool xml_text::set(float rhs);
|
||||
bool xml_text::set(float rhs, int precision);
|
||||
bool xml_text::set(bool rhs);
|
||||
bool xml_text::set(long long rhs);
|
||||
bool xml_text::set(unsigned long long rhs);
|
||||
|
@ -1629,12 +1597,12 @@ bool xml_document::save_file(const char* path, const char_t* indent = "\t", unsi
|
|||
bool xml_document::save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
|
||||
----
|
||||
|
||||
These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <<saving.options>>) and output data encoding (see <<saving.encoding>>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. The functions return `true` on success and `false` if the file could not be opened or written to.
|
||||
These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <<saving.options>>) and output data encoding (see <<saving.encoding>>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc.
|
||||
|
||||
File path is passed to the system file opening function as is in case of the first function (which accepts `const char* path`); the second function either uses a special file opening function if it is provided by the runtime library or converts the path to UTF-8 and uses the system file opening function.
|
||||
|
||||
[[xml_writer_file]]
|
||||
`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <<saving.writer>> for writer interface details.
|
||||
`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. If the file could not be opened, the function returns `false`. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <<saving.writer>> for writer interface details.
|
||||
|
||||
This is a simple example of saving XML document to file (link:samples/save_file.cpp[]):
|
||||
|
||||
|
@ -1736,10 +1704,6 @@ These flags control the resulting tree contents:
|
|||
|
||||
* [[format_no_empty_element_tags]]`format_no_empty_element_tags` determines if start/end tags should be output instead of empty element tags for empty elements (that is, elements with no children). This flag is *off* by default.
|
||||
|
||||
* [[format_skip_control_chars]]`format_skip_control_chars` enables skipping characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is *off* by default.
|
||||
|
||||
* [[format_attribute_single_quote]]`format_attribute_single_quote` enables using single quotes `'` instead of double quotes `"` for enclosing attribute values. This flag is *off* by default.
|
||||
|
||||
These flags control the additional output information:
|
||||
|
||||
* [[format_no_declaration]]`format_no_declaration` disables default node declaration output. By default, if the document is saved via `save` or `save_file` function, and it does not have any document declaration, a default declaration is output before the document contents. Enabling this flag disables this declaration. This flag has no effect in `xml_node::print` functions: they never output the default declaration. This flag is *off* by default.
|
||||
|
@ -2163,90 +2127,6 @@ Because of the differences in document object models, performance considerations
|
|||
|
||||
:!numbered:
|
||||
|
||||
[[v1.13]]
|
||||
=== v1.13 ^2022-11-01^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Improvements:
|
||||
. `xml_attribute::set_value`, `xml_node::set_value` and `xml_text::set` now have overloads that accept pointer to non-null-terminated string and size
|
||||
. Improve performance of tree traversal when using compact mode (`PUGIXML_COMPACT`)
|
||||
|
||||
* Bug fixes:
|
||||
. Fix error handling in `xml_document::save_file` that could result in the function succeeding while running out of disk space
|
||||
. Fix memory leak during error handling of some out-of-memory conditions during `xml_document::load`
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix exported symbols in CMake DLL builds when using CMake
|
||||
. Fix exported symbols in CMake shared object builds when using -fvisibility=hidden
|
||||
|
||||
[[v1.12]]
|
||||
=== v1.12 ^2022-02-09^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Bug fixes:
|
||||
. Fix a bug in xml_document move construction when the source of the move is empty
|
||||
. Fix const-correctness issues with iterator objects to support C++20 ranges
|
||||
|
||||
* XPath improvements:
|
||||
. Improved detection of overly complex queries that may result in stack overflow during parsing
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix Cygwin support for DLL builds
|
||||
. Fix Windows CE support
|
||||
. Add NuGet builds and project files for VS2022
|
||||
|
||||
* Build system changes
|
||||
. All CMake options now have the prefix `PUGIXML_`. This may require changing dependent build configurations.
|
||||
. Many build settings are now exposed via CMake settings, most notably `PUGIXML_COMPACT` and `PUGIXML_WCHAR_MODE` can be set without changing `pugiconfig.hpp`
|
||||
|
||||
[[v1.11]]
|
||||
=== v1.11 ^2020-11-26^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* New features:
|
||||
. Add xml_node::remove_attributes and xml_node::remove_children
|
||||
. Add a way to customize floating point precision via xml_attribute::set and xml_text::set overloads
|
||||
|
||||
* XPath improvements:
|
||||
. XPath parser now limits recursion depth which prevents stack overflow on malicious queries
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix Visual Studio warnings when built using clang-cl compiler
|
||||
. Fix Wconversion warnings in gcc
|
||||
. Fix Wzero-as-null-pointer-constant warnings in pugixml.hpp
|
||||
. Work around several static analysis false positives
|
||||
|
||||
* Build system changes
|
||||
. The CMake package for pugixml now provides a `pugixml::pugixml` target rather than a `pugixml` target. A compatibility `pugixml` target is provided if at least version 1.11 is not requested.
|
||||
|
||||
[[v1.10]]
|
||||
=== v1.10 ^2019-09-15^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Behavior changes:
|
||||
. Tab characters (ASCII 9) in attribute values are now encoded as '	' to survive roundtripping
|
||||
. `>` characters are no longer escaped in attribute values
|
||||
|
||||
* New features:
|
||||
. Add Visual Studio .natvis files to improve debugging experience
|
||||
. CMake improvements (USE_POSTFIX and BUILD_SHARED_AND_STATIC_LIBS options for building multiple versions and pkg-config tweaks)
|
||||
. Add format_skip_control_chars formatting flag to skip non-printable ASCII characters that are invalid to use in well-formed XML files
|
||||
. Add format_attribute_single_quote formatting flag to use single quotes for attribute values instead of default double quotes.
|
||||
|
||||
* XPath improvements:
|
||||
. XPath union now results in a stable order that doesn't depend on memory allocations; crucially, this may require sorting the output of XPath query operation if you rely on the document-ordered traversal
|
||||
. Improve performance of XPath union operation, making it ~2x faster
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix Visual Studio warnings when built in a DLL configuration
|
||||
. Fix static analysis false positives in Coverity and clang
|
||||
. Fix Wdouble-promotion warnings in gcc
|
||||
. Add Visual Studio 2019 support for NuGet packages
|
||||
|
||||
[[v1.9]]
|
||||
=== v1.9 ^2018-04-04^
|
||||
|
||||
|
@ -2771,7 +2651,6 @@ enum +++<a href="#xpath_value_type">xpath_value_type</a>+++
|
|||
[source,subs="+macros"]
|
||||
----
|
||||
// Formatting options bit flags:
|
||||
const unsigned int +++<a href="#format_attribute_single_quote">format_attribute_single_quote</a>+++
|
||||
const unsigned int +++<a href="#format_default">format_default</a>+++
|
||||
const unsigned int +++<a href="#format_indent">format_indent</a>+++
|
||||
const unsigned int +++<a href="#format_indent_attributes">format_indent_attributes</a>+++
|
||||
|
@ -2780,7 +2659,6 @@ const unsigned int +++<a href="#format_no_empty_element_tags">format_no_empty_el
|
|||
const unsigned int +++<a href="#format_no_escapes">format_no_escapes</a>+++
|
||||
const unsigned int +++<a href="#format_raw">format_raw</a>+++
|
||||
const unsigned int +++<a href="#format_save_file_text">format_save_file_text</a>+++
|
||||
const unsigned int +++<a href="#format_skip_control_chars">format_skip_control_chars</a>+++
|
||||
const unsigned int +++<a href="#format_write_bom">format_write_bom</a>+++
|
||||
|
||||
// Parsing options bit flags:
|
||||
|
@ -2840,7 +2718,6 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||
|
||||
bool +++<a href="#xml_attribute::set_name">set_name</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(int rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(long rhs);
|
||||
|
@ -2899,9 +2776,6 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||
xml_attribute +++<a href="#xml_node::attribute">attribute</a>+++(const char_t* name) const;
|
||||
xml_node +++<a href="#xml_node::next_sibling_name">next_sibling</a>+++(const char_t* name) const;
|
||||
xml_node +++<a href="#xml_node::previous_sibling_name">previous_sibling</a>+++(const char_t* name) const;
|
||||
|
||||
xml_attribute +++<a href="#xml_node::attribute_hinted">attribute</a>+++(const char_t* name, xml_attribute& hint) const;
|
||||
|
||||
xml_node +++<a href="#xml_node::find_child_by_attribute">find_child_by_attribute</a>+++(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
|
||||
xml_node +++<a href="#xml_node::find_child_by_attribute">find_child_by_attribute</a>+++(const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
|
@ -2930,7 +2804,6 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||
|
||||
bool +++<a href="#xml_node::set_name">set_name</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_node::set_value">set_value</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_node::set_value">set_value</a>+++(const char_t* rhs, size_t size);
|
||||
|
||||
xml_attribute +++<a href="#xml_node::append_attribute">append_attribute</a>+++(const char_t* name);
|
||||
xml_attribute +++<a href="#xml_node::prepend_attribute">prepend_attribute</a>+++(const char_t* name);
|
||||
|
@ -2964,10 +2837,8 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||
|
||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const xml_attribute& a);
|
||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const char_t* name);
|
||||
bool +++<a href="#xml_node::remove_attributes">remove_attributes</a>+++();
|
||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const xml_node& n);
|
||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const char_t* name);
|
||||
bool +++<a href="#xml_node::remove_children">remove_children</a>+++();
|
||||
|
||||
xml_parse_result +++<a href="#xml_node::append_buffer">append_buffer</a>+++(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
||||
|
||||
|
@ -3043,17 +2914,16 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
|||
unsigned long long +++<a href="#xml_text::as_ullong">as_ullong</a>+++(unsigned long long def = 0) const;
|
||||
|
||||
bool +++<a href="#xml_text::set">set</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(const char_t* rhs, size_t size);
|
||||
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(int rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(double rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(float rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(bool rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(long long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned long long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(int rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(double rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(float rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(bool rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(long long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned long long rhs);
|
||||
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(const char_t* rhs);
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(int rhs);
|
||||
|
|
2884
docs/manual.html
2884
docs/manual.html
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@ include::config.adoc[]
|
|||
[[introduction]]
|
||||
== Introduction
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
@ -25,7 +25,7 @@ The distribution contains library source, documentation (the guide you're readin
|
|||
|
||||
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.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
|
||||
|
@ -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-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2018 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
@ -282,6 +282,6 @@ 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-2018 Arseny Kapoulkine.
|
||||
....
|
||||
|
|
File diff suppressed because it is too large
Load diff
10
readme.txt
10
readme.txt
|
@ -1,7 +1,7 @@
|
|||
pugixml 1.13 - an XML processing library
|
||||
pugixml 1.9 - an XML processing library
|
||||
|
||||
Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
Report bugs and download new versions at https://pugixml.org/
|
||||
Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
Report bugs and download new versions at http://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,6 +13,8 @@ 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
|
||||
|
@ -26,7 +28,7 @@ The distribution contains the following folders:
|
|||
|
||||
This library is distributed under the MIT License:
|
||||
|
||||
Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2018 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import io
|
||||
import os.path
|
||||
import sys
|
||||
import tarfile
|
||||
import time
|
||||
import zipfile
|
||||
import StringIO
|
||||
|
||||
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 '\0' not in data:
|
||||
data = data.replace('\r', '')
|
||||
if use_crlf:
|
||||
data = data.replace(b'\n', b'\r\n')
|
||||
data = data.replace('\n', '\r\n')
|
||||
|
||||
return data
|
||||
|
||||
|
@ -24,7 +24,7 @@ def write_zip(target, arcprefix, timestamp, sources):
|
|||
info = zipfile.ZipInfo(path)
|
||||
info.date_time = time.localtime(timestamp)
|
||||
info.compress_type = zipfile.ZIP_DEFLATED
|
||||
info.external_attr = 0o644 << 16
|
||||
info.external_attr = 0644 << 16L
|
||||
archive.writestr(info, data)
|
||||
|
||||
def write_tar(target, arcprefix, timestamp, sources, compression):
|
||||
|
@ -35,7 +35,7 @@ def write_tar(target, arcprefix, timestamp, sources, compression):
|
|||
info = tarfile.TarInfo(path)
|
||||
info.size = len(data)
|
||||
info.mtime = timestamp
|
||||
archive.addfile(info, io.BytesIO(data))
|
||||
archive.addfile(info, StringIO.StringIO(data))
|
||||
|
||||
if len(sys.argv) < 5:
|
||||
raise RuntimeError('Usage: python archive.py <target> <archive prefix> <timestamp> <source files>')
|
||||
|
|
|
@ -1,506 +0,0 @@
|
|||
<?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 & 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)&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 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(attribute_this - attribute_T1)" />
|
||||
<Variable Name="page" InitialValue="((attribute_this - attribute_T1 - (_page << compact_alignment_log2)) - *(unsigned*)(attribute_this - attribute_T1 - (_page << 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 & ~(compact_alignment - 1)) + (attribute_data - 1 + attribute_T2) * compact_alignment)" />
|
||||
|
||||
<Variable Name="number" InitialValue="0" />
|
||||
|
||||
<!-- Loop over all attributes -->
|
||||
<Loop Condition="attribute_this && 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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
|
||||
<Exec>attribute_data_copy = attribute_data</Exec>
|
||||
|
||||
<If Condition="attribute_data_copy >= 255 && attribute_real">
|
||||
<Item Name="[{number}]">*attribute_real,view(child)</Item>
|
||||
<Exec>attribute_this = (size_t)&(*attribute_real).next_attribute</Exec>
|
||||
<Exec>attribute_data = (*attribute_real).next_attribute._data</Exec>
|
||||
</If>
|
||||
<If Condition="attribute_data_copy < 255 && attribute_short">
|
||||
<Item Name="[{number}]">*attribute_short,view(child)</Item>
|
||||
<Exec>attribute_this = (size_t)&(*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 & ~(compact_alignment - 1)) + (attribute_data - 1 + attribute_T2) * compact_alignment)</Exec>
|
||||
|
||||
<Exec>number++</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Synthetic>
|
||||
|
||||
<CustomListItems>
|
||||
<Variable Name="child_this" InitialValue="&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 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(child_this - child_T1)" />
|
||||
<Variable Name="page" InitialValue="((child_this - child_T1 - (_page << compact_alignment_log2)) - *(unsigned*)(child_this - child_T1 - (_page << 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 & ~(compact_alignment - 1)) + (child_data - 1 + child_T2) * compact_alignment)" />
|
||||
|
||||
<Variable Name="number" InitialValue="0" />
|
||||
|
||||
<Loop Condition="child_this && 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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
|
||||
<Exec>child_data_copy = child_data</Exec>
|
||||
|
||||
<If Condition="child_data_copy >= 255 && child_real">
|
||||
<Item Name="[{number}]">*child_real,view(child)</Item>
|
||||
<Exec>child_this = (size_t)&(*child_real).next_sibling</Exec>
|
||||
<Exec>child_data = (*child_real).next_sibling._data</Exec>
|
||||
</If>
|
||||
<If Condition="child_data_copy < 255 && child_short">
|
||||
<Item Name="[{number}]">*child_short,view(child)</Item>
|
||||
<Exec>child_this = (size_t)&(*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 & ~(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="&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 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(attribute_this - attribute_T1)" />
|
||||
<Variable Name="page" InitialValue="((attribute_this - attribute_T1 - (_page << compact_alignment_log2)) - *(unsigned*)(attribute_this - attribute_T1 - (_page << 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 & ~(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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
|
||||
<If Condition="attribute_data >= 255 && attribute_real">
|
||||
<Item Name="next_attribute">*attribute_real</Item>
|
||||
</If>
|
||||
<If Condition="attribute_data != 0 && attribute_data < 255 && attribute_short">
|
||||
<Item Name="next_attribute">*attribute_short</Item>
|
||||
</If>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="pugi::impl::`anonymous-namespace'::compact_string<*,*>">
|
||||
<Expand HideRawView="1">
|
||||
<CustomListItems Condition="_data && _data < 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
|
||||
<Variable Name="page" InitialValue="((this - $T1 - (_page << compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page << 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) << 7) + (_data - 1)" />
|
||||
|
||||
<Item Name="value">(pugi::char_t*)(compact_string_base + offset * sizeof(pugi::char_t)),na</Item>
|
||||
</CustomListItems>
|
||||
|
||||
<CustomListItems Condition="_data && _data >= 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
|
||||
<Variable Name="page" InitialValue="((this - $T1 - (_page << compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page << 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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="pugi::impl::`anonymous-namespace'::compact_pointer<pugi::xml_node_struct,*,*>">
|
||||
<DisplayString Condition="!_data">nullptr</DisplayString>
|
||||
<DisplayString Condition="_data">...</DisplayString>
|
||||
|
||||
<Expand HideRawView="1">
|
||||
<CustomListItems Condition="_data && _data < 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<Item Name="value">*(pugi::xml_node_struct*)(((size_t)this & ~(compact_alignment - 1)) + (_data - 1 + $T2) * compact_alignment)</Item>
|
||||
</CustomListItems>
|
||||
|
||||
<CustomListItems Condition="_data && _data >= 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
|
||||
<Variable Name="page" InitialValue="((this - $T1 - (_page << compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page << 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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="pugi::impl::`anonymous-namespace'::compact_pointer<pugi::xml_attribute_struct,*,*>">
|
||||
<DisplayString Condition="!_data">nullptr</DisplayString>
|
||||
<DisplayString Condition="_data">...</DisplayString>
|
||||
|
||||
<Expand HideRawView="1">
|
||||
<CustomListItems Condition="_data && _data < 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<Item Name="value">*(pugi::xml_attribute_struct*)(((size_t)this & ~(compact_alignment - 1)) + (_data - 1 + $T2) * compact_alignment)</Item>
|
||||
</CustomListItems>
|
||||
|
||||
<CustomListItems Condition="_data && _data >= 255">
|
||||
<Variable Name="compact_alignment_log2" InitialValue="2" />
|
||||
<Variable Name="compact_alignment" InitialValue="1 << compact_alignment_log2" />
|
||||
|
||||
<!-- compact_get_page() -->
|
||||
<Variable Name="_page" InitialValue="*(char*)(this - $T1)" />
|
||||
<Variable Name="page" InitialValue="((this - $T1 - (_page << compact_alignment_log2)) - *(unsigned*)(this - $T1 - (_page << 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 & hashmod</Exec>
|
||||
|
||||
<!-- find() loop -->
|
||||
<Loop Condition="probe <= hashmod &&_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) & hashmod</Exec>
|
||||
<Exec>probe++</Exec>
|
||||
</Loop>
|
||||
</CustomListItems>
|
||||
</Expand>
|
||||
</Type>
|
||||
|
||||
<Type Name="pugi::xpath_node">
|
||||
<DisplayString Condition="_node._root && _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 && !_attribute._attr">_node</ExpandedItem>
|
||||
<ExpandedItem Condition="!_node._root && _attribute._attr">_attribute</ExpandedItem>
|
||||
|
||||
<Item Name="node" Condition="_node._root && _attribute._attr">_node,na</Item>
|
||||
<Item Name="attribute" Condition="_node._root && _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>
|
|
@ -10,8 +10,6 @@
|
|||
<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>
|
||||
|
|
|
@ -2,27 +2,26 @@
|
|||
<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>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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'">
|
||||
<ItemDefinitionGroup Condition="$(Configuration.ToLower().IndexOf('debug')) != -1">
|
||||
<Link>
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/$(Platform)\$(PlatformToolset.Split('_')[0])\$(Linkage-pugixml)\$(Configuration-pugixml)\pugixml.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/$(Platform)\$(PlatformToolset.Split('_')[0])\$(Linkage-pugixml)\Debug\pugixml.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="$(Configuration.ToLower().IndexOf('debug')) == -1">
|
||||
<Link>
|
||||
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib/$(Platform)\$(PlatformToolset.Split('_')[0])\$(Linkage-pugixml)\Release\pugixml.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
|
|
|
@ -2,19 +2,20 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>pugixml</id>
|
||||
<version>1.13.0-appveyor</version>
|
||||
<version>1.9.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>
|
||||
<licenseUrl>http://pugixml.org/license.html</licenseUrl>
|
||||
<projectUrl>http://pugixml.org/</projectUrl>
|
||||
<iconUrl>https://github.com/zeux/pugixml/logo.svg</iconUrl>
|
||||
<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>
|
||||
This package contains builds for VS2013, VS2015 and VS2017, 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>
|
||||
<releaseNotes>http://pugixml.org/docs/manual.html#changes</releaseNotes>
|
||||
<copyright>Copyright (c) 2006-2018 Arseny Kapoulkine</copyright>
|
||||
<tags>native nativepackage</tags>
|
||||
</metadata>
|
||||
</package>
|
||||
|
|
|
@ -33,37 +33,15 @@ 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"
|
||||
Build-Version "vs2013" "v120" "dynamic"
|
||||
Build-Version "vs2013" "v120" "static"
|
||||
|
||||
} elseif ($args[0] -eq 2019){
|
||||
Build-Version "vs2019" "v142" "dynamic"
|
||||
Build-Version "vs2019" "v142" "static"
|
||||
Build-Version "vs2015" "v140" "dynamic"
|
||||
Build-Version "vs2015" "v140" "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"
|
||||
}
|
||||
Build-Version "vs2017" "v141" "dynamic"
|
||||
Build-Version "vs2017" "v141" "static"
|
||||
|
||||
Run-Command "nuget pack nuget"
|
||||
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
@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 ()
|
|
@ -1,11 +1,11 @@
|
|||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@@INSTALL_SUFFIX@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@@INSTALL_SUFFIX@
|
||||
includedir=${prefix}/include@INSTALL_SUFFIX@
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@@INSTALL_SUFFIX@
|
||||
|
||||
Name: pugixml
|
||||
Description: Light-weight, simple and fast XML parser for C++ with XPath support.
|
||||
URL: https://pugixml.org/
|
||||
URL: http://pugixml.org/
|
||||
Version: @pugixml_VERSION@
|
||||
Cflags: -I${includedir}
|
||||
Libs: -L${libdir} -lpugixml@LIB_POSTFIX@
|
||||
Libs: -L${libdir} -lpugixml
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = "pugixml"
|
||||
s.version = "1.13"
|
||||
s.version = "1.9"
|
||||
s.summary = "C++ XML parser library."
|
||||
s.homepage = "https://pugixml.org"
|
||||
s.homepage = "http://pugixml.org"
|
||||
s.license = "MIT"
|
||||
s.author = { "Arseny Kapoulkine" => "arseny.kapoulkine@gmail.com" }
|
||||
s.platform = :ios, "7.0"
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
#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
|
|
@ -1,172 +0,0 @@
|
|||
<?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>
|
|
@ -1,176 +0,0 @@
|
|||
<?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>
|
|
@ -1,172 +0,0 @@
|
|||
<?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>
|
|
@ -1,176 +0,0 @@
|
|||
<?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>
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* pugixml parser - version 1.13
|
||||
* pugixml parser - version 1.9
|
||||
* --------------------------------------------------------
|
||||
* Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at https://pugixml.org/
|
||||
* Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at http://pugixml.org/
|
||||
*
|
||||
* This library is distributed under the MIT License. See notice at the end
|
||||
* of this file.
|
||||
|
@ -40,9 +40,6 @@
|
|||
// #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
|
||||
|
||||
|
@ -52,7 +49,7 @@
|
|||
#endif
|
||||
|
||||
/**
|
||||
* Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
* Copyright (c) 2006-2018 Arseny Kapoulkine
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
|
25054
src/pugixml.cpp
25054
src/pugixml.cpp
File diff suppressed because it is too large
Load diff
2616
src/pugixml.hpp
2616
src/pugixml.hpp
File diff suppressed because it is too large
Load diff
|
@ -1,144 +1,146 @@
|
|||
#include "allocator.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Address sanitizer
|
||||
#if defined(__has_feature)
|
||||
# define ADDRESS_SANITIZER __has_feature(address_sanitizer)
|
||||
#define ADDRESS_SANITIZER __has_feature(address_sanitizer)
|
||||
#else
|
||||
# if defined(__SANITIZE_ADDRESS__)
|
||||
# define ADDRESS_SANITIZER 1
|
||||
# else
|
||||
# define ADDRESS_SANITIZER 0
|
||||
# endif
|
||||
#if defined(__SANITIZE_ADDRESS__)
|
||||
#define ADDRESS_SANITIZER 1
|
||||
#else
|
||||
#define ADDRESS_SANITIZER 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Low-level allocation functions
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# ifdef __MWERKS__
|
||||
# pragma ANSI_strict off // disable ANSI strictness to include windows.h
|
||||
# pragma cpp_extensions on // enable some extensions to include windows.h
|
||||
# endif
|
||||
#ifdef __MWERKS__
|
||||
#pragma ANSI_strict off // disable ANSI strictness to include windows.h
|
||||
#pragma cpp_extensions on // enable some extensions to include windows.h
|
||||
#endif
|
||||
|
||||
# if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
|
||||
# endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4201) // nonstandard extension used: nameless struct/union
|
||||
#endif
|
||||
|
||||
# ifdef _XBOX_VER
|
||||
# define NOD3D
|
||||
# include <xtl.h>
|
||||
# else
|
||||
# include <windows.h>
|
||||
# endif
|
||||
#ifdef _XBOX_VER
|
||||
#define NOD3D
|
||||
#include <xtl.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t page_size = 4096;
|
||||
const size_t page_size = 4096;
|
||||
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
// We can't use VirtualAlloc because it has 64Kb granularity so we run out of address space quickly
|
||||
// We can't use malloc because of occasional problems with CW on CRT termination
|
||||
static HANDLE heap = HeapCreate(0, 0, 0);
|
||||
|
||||
void* result = HeapAlloc(heap, 0, size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr) return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(end, page_size, PAGE_NOACCESS, &old_flags);
|
||||
|
||||
return end - size;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(rptr, aligned_size + page_size, PAGE_NOACCESS, &old_flags);
|
||||
}
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
// We can't use VirtualAlloc because it has 64Kb granularity so we run out of address space quickly
|
||||
// We can't use malloc because of occasional problems with CW on CRT termination
|
||||
static HANDLE heap = HeapCreate(0, 0, 0);
|
||||
|
||||
void* result = HeapAlloc(heap, 0, size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(end, page_size, PAGE_NOACCESS, &old_flags);
|
||||
|
||||
return end - size;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
|
||||
DWORD old_flags;
|
||||
VirtualProtect(rptr, aligned_size + page_size, PAGE_NOACCESS, &old_flags);
|
||||
}
|
||||
} // namespace
|
||||
#elif (defined(__APPLE__) || defined(__linux__)) && (defined(__i386) || defined(__x86_64)) && !ADDRESS_SANITIZER
|
||||
# include <sys/mman.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t page_size = 4096;
|
||||
const size_t page_size = 4096;
|
||||
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
void* result = malloc(size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr) return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
int res = mprotect(end, page_size, PROT_NONE);
|
||||
assert(res == 0);
|
||||
(void)!res;
|
||||
|
||||
return end - size;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
|
||||
int res = mprotect(rptr, aligned_size + page_size, PROT_NONE);
|
||||
assert(res == 0);
|
||||
(void)!res;
|
||||
}
|
||||
size_t align_to_page(size_t value)
|
||||
{
|
||||
return (value + page_size - 1) & ~(page_size - 1);
|
||||
}
|
||||
|
||||
void* allocate_page_aligned(size_t size)
|
||||
{
|
||||
void* result = malloc(size + page_size);
|
||||
|
||||
return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* ptr = allocate_page_aligned(aligned_size + page_size);
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
char* end = static_cast<char*>(ptr) + aligned_size;
|
||||
|
||||
int res = mprotect(end, page_size, PROT_NONE);
|
||||
assert(res == 0);
|
||||
(void)!res;
|
||||
|
||||
return end - size;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
size_t aligned_size = align_to_page(size);
|
||||
|
||||
void* rptr = static_cast<char*>(ptr) + size - aligned_size;
|
||||
|
||||
int res = mprotect(rptr, aligned_size + page_size, PROT_NONE);
|
||||
assert(res == 0);
|
||||
(void)!res;
|
||||
}
|
||||
} // namespace
|
||||
#else
|
||||
namespace
|
||||
{
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
(void)size;
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr, size_t size)
|
||||
{
|
||||
(void)size;
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
// High-level allocation functions
|
||||
|
@ -147,7 +149,8 @@ const size_t memory_alignment = sizeof(double) > sizeof(void*) ? sizeof(double)
|
|||
void* memory_allocate(size_t size)
|
||||
{
|
||||
void* result = allocate(size + memory_alignment);
|
||||
if (!result) return 0;
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
memcpy(result, &size, sizeof(size_t));
|
||||
|
||||
|
@ -166,10 +169,10 @@ size_t memory_size(void* ptr)
|
|||
|
||||
void memory_deallocate(void* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
size_t size = memory_size(ptr);
|
||||
|
||||
deallocate(static_cast<char*>(ptr) - memory_alignment, size + memory_alignment);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,18 +18,11 @@ foreach ($vs in $args)
|
|||
{
|
||||
Write-Output "# Setting up VS$vs $arch"
|
||||
|
||||
if ($vs -eq 15) {
|
||||
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
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_document doc;
|
||||
|
||||
doc.load_buffer(Data, Size);
|
||||
doc.load_buffer(Data, Size, pugi::parse_minimal);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
|
||||
{
|
||||
char* text = new char[Size + 1];
|
||||
memcpy(text, Data, Size);
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
#include <utility>
|
||||
|
||||
template <typename T> static void generic_bool_ops_test(const T& obj)
|
||||
template <typename T>
|
||||
static void generic_bool_ops_test(const T& obj)
|
||||
{
|
||||
T null;
|
||||
|
||||
|
@ -14,14 +15,14 @@ template <typename T> static void generic_bool_ops_test(const T& obj)
|
|||
CHECK(!!obj);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4800) // forcing value to bool 'true' or 'false' (performance warning) - we really want to just cast to bool instead of !!
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4800) // forcing value to bool 'true' or 'false' (performance warning) - we really want to just cast to bool instead of !!
|
||||
#endif
|
||||
|
||||
bool b1 = null, b2 = obj;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
CHECK(!b1);
|
||||
|
@ -33,7 +34,8 @@ template <typename T> static void generic_bool_ops_test(const T& obj)
|
|||
CHECK(obj || obj);
|
||||
}
|
||||
|
||||
template <typename T> static void generic_eq_ops_test(const T& obj1, const T& obj2)
|
||||
template <typename T>
|
||||
static void generic_eq_ops_test(const T& obj1, const T& obj2)
|
||||
{
|
||||
T null = T();
|
||||
|
||||
|
@ -54,7 +56,8 @@ template <typename T> static void generic_eq_ops_test(const T& obj1, const T& ob
|
|||
CHECK(!(T(obj1) != obj1));
|
||||
}
|
||||
|
||||
template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
|
||||
template <typename T>
|
||||
static void generic_rel_ops_test(T obj1, T obj2)
|
||||
{
|
||||
T null = T();
|
||||
|
||||
|
@ -103,7 +106,8 @@ template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
|
|||
CHECK(!(obj1 >= obj2));
|
||||
}
|
||||
|
||||
template <typename T> static void generic_empty_test(const T& obj)
|
||||
template <typename T>
|
||||
static void generic_empty_test(const T& obj)
|
||||
{
|
||||
T null;
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
#include "test.hpp"
|
||||
#include "allocator.hpp"
|
||||
#include "test.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
# include <exception>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
# undef DebugBreak
|
||||
# pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union
|
||||
# include <windows.h>
|
||||
#undef DebugBreak
|
||||
#pragma warning(disable : 4201) // nonstandard extension used: nameless struct/union
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
test_runner* test_runner::_tests = 0;
|
||||
|
@ -41,7 +41,8 @@ static void* custom_allocate(size_t size)
|
|||
else
|
||||
{
|
||||
void* ptr = memory_allocate(size);
|
||||
if (!ptr) return 0;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
|
||||
g_memory_total_size += memory_size(ptr);
|
||||
g_memory_total_count++;
|
||||
|
@ -89,9 +90,9 @@ static void replace_memory_management()
|
|||
|
||||
namespace std
|
||||
{
|
||||
_CRTIMP2 _Prhand _Raise_handler;
|
||||
_CRTIMP2 void __cdecl _Throw(const exception&) {}
|
||||
}
|
||||
_CRTIMP2 _Prhand _Raise_handler;
|
||||
_CRTIMP2 void __cdecl _Throw(const exception&) {}
|
||||
} // namespace std
|
||||
#endif
|
||||
|
||||
static bool run_test(test_runner* test, const char* test_name, pugi::allocation_function allocate)
|
||||
|
@ -109,15 +110,15 @@ static bool run_test(test_runner* test, const char* test_name, pugi::allocation_
|
|||
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
|
||||
# pragma warning(disable: 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4611) // interaction between _setjmp and C++ object destruction is non-portable
|
||||
#pragma warning(disable : 4793) // function compiled as native: presence of '_setjmp' makes a function unmanaged
|
||||
#endif
|
||||
|
||||
volatile int result = setjmp(test_runner::_failure_buffer);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
|
@ -193,10 +194,10 @@ int main(int, char** argv)
|
|||
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
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
total++;
|
||||
passed += run_test(test, (test->_name + std::string(" (throw)")).c_str(), custom_allocate_throw);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
|
@ -33,10 +33,12 @@ static void build_document_order(std::vector<pugi::xpath_node>& result, pugi::xm
|
|||
cur = cur.next_sibling();
|
||||
else
|
||||
{
|
||||
while (cur && !cur.next_sibling()) cur = cur.parent();
|
||||
while (cur && !cur.next_sibling())
|
||||
cur = cur.parent();
|
||||
cur = cur.next_sibling();
|
||||
|
||||
if (!cur) break;
|
||||
if (!cur)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +47,11 @@ static void build_document_order(std::vector<pugi::xpath_node>& result, pugi::xm
|
|||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs)
|
||||
{
|
||||
return (!lhs || !rhs) ? lhs == rhs :
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wcscmp(lhs, rhs) == 0;
|
||||
#else
|
||||
strcmp(lhs, rhs) == 0;
|
||||
#endif
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wcscmp(lhs, rhs) == 0;
|
||||
#else
|
||||
strcmp(lhs, rhs) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool test_node(const pugi::xml_node& node, const pugi::char_t* contents, const pugi::char_t* indent, unsigned int flags)
|
||||
|
@ -83,7 +85,8 @@ static size_t strlength(const pugi::char_t* s)
|
|||
bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, const pugi::char_t* expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
const size_t capacity = 64;
|
||||
pugi::char_t result[capacity];
|
||||
|
@ -104,7 +107,8 @@ bool test_xpath_string(const pugi::xpath_node& node, const pugi::char_t* query,
|
|||
bool test_xpath_boolean(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, bool expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
return q.evaluate_boolean(node) == expected;
|
||||
}
|
||||
|
@ -112,19 +116,21 @@ bool test_xpath_boolean(const pugi::xpath_node& node, const pugi::char_t* query,
|
|||
bool test_xpath_number(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables, double expected)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
double value = q.evaluate_number(node);
|
||||
double absolute_error = fabs(value - expected);
|
||||
|
||||
const double tolerance = 1e-15;
|
||||
const double tolerance = 1e-15f;
|
||||
return absolute_error < tolerance || absolute_error < fabs(expected) * tolerance;
|
||||
}
|
||||
|
||||
bool test_xpath_number_nan(const pugi::xpath_node& node, const pugi::char_t* query, pugi::xpath_variable_set* variables)
|
||||
{
|
||||
pugi::xpath_query q(query, variables);
|
||||
if (!q) return false;
|
||||
if (!q)
|
||||
return false;
|
||||
|
||||
return test_double_nan(q.evaluate_number(node));
|
||||
}
|
||||
|
@ -155,12 +161,15 @@ void xpath_node_set_tester::check(bool condition)
|
|||
}
|
||||
}
|
||||
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message_): last(0), message(message_)
|
||||
xpath_node_set_tester::xpath_node_set_tester(const pugi::xpath_node_set& set, const char* message_)
|
||||
: last(0)
|
||||
, message(message_)
|
||||
{
|
||||
result = set;
|
||||
|
||||
// only sort unsorted sets so that we're able to verify reverse order for some axes
|
||||
if (result.type() == pugi::xpath_node_set::type_unsorted) result.sort();
|
||||
if (result.type() == pugi::xpath_node_set::type_unsorted)
|
||||
result.sort();
|
||||
|
||||
if (result.empty())
|
||||
{
|
||||
|
|
|
@ -36,7 +36,8 @@ struct test_runner
|
|||
|
||||
bool test_string_equal(const pugi::char_t* lhs, const pugi::char_t* rhs);
|
||||
|
||||
template <typename Node> inline bool test_node_name_value(const Node& node, const pugi::char_t* name, const pugi::char_t* value)
|
||||
template <typename Node>
|
||||
inline bool test_node_name_value(const Node& node, const pugi::char_t* name, const pugi::char_t* value)
|
||||
{
|
||||
return test_string_equal(node.name(), name) && test_string_equal(node.value(), value);
|
||||
}
|
||||
|
@ -71,17 +72,22 @@ struct xpath_node_set_tester
|
|||
|
||||
#endif
|
||||
|
||||
struct dummy_fixture {};
|
||||
struct dummy_fixture
|
||||
{
|
||||
};
|
||||
|
||||
#define TEST_FIXTURE(name, fixture) \
|
||||
struct test_runner_helper_##name: fixture \
|
||||
struct test_runner_helper_##name : fixture \
|
||||
{ \
|
||||
void run(); \
|
||||
}; \
|
||||
static struct test_runner_##name: test_runner \
|
||||
static struct test_runner_##name : test_runner \
|
||||
{ \
|
||||
test_runner_##name(): test_runner(#name) {} \
|
||||
\
|
||||
test_runner_##name() \
|
||||
: test_runner(#name) \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
virtual void run() PUGIXML_OVERRIDE \
|
||||
{ \
|
||||
test_runner_helper_##name helper; \
|
||||
|
@ -96,30 +102,34 @@ struct dummy_fixture {};
|
|||
struct test_fixture_##name \
|
||||
{ \
|
||||
pugi::xml_document doc; \
|
||||
\
|
||||
\
|
||||
test_fixture_##name() \
|
||||
{ \
|
||||
CHECK(doc.load_string(PUGIXML_TEXT(xml), flags)); \
|
||||
} \
|
||||
\
|
||||
\
|
||||
private: \
|
||||
test_fixture_##name(const test_fixture_##name&); \
|
||||
test_fixture_##name& operator=(const test_fixture_##name&); \
|
||||
}; \
|
||||
\
|
||||
\
|
||||
TEST_FIXTURE(name, test_fixture_##name)
|
||||
|
||||
#define TEST_XML(name, xml) TEST_XML_FLAGS(name, xml, pugi::parse_default)
|
||||
|
||||
#define CHECK_JOIN(text, file, line) text " at " file ":" #line
|
||||
#define CHECK_JOIN2(text, file, line) CHECK_JOIN(text, file, line)
|
||||
#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_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__) || (defined(__BORLANDC__) && __BORLANDC__ <= 0x540)
|
||||
# define STRINGIZE(value) "??" // Some compilers have issues with stringizing expressions that contain strings w/escaping inside
|
||||
#define STRINGIZE(value) "??" // Some compilers have issues with stringizing expressions that contain strings w/escaping inside
|
||||
#else
|
||||
# define STRINGIZE(value) #value
|
||||
#define STRINGIZE(value) #value
|
||||
#endif
|
||||
|
||||
#define CHECK(condition) CHECK_TEXT(condition, STRINGIZE(condition) " is false")
|
||||
|
@ -147,9 +157,29 @@ struct dummy_fixture {};
|
|||
#endif
|
||||
|
||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
||||
#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); code; CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)
|
||||
#define CHECK_ALLOC_FAIL(code) \
|
||||
do \
|
||||
{ \
|
||||
CHECK(!test_runner::_memory_fail_triggered); \
|
||||
code; \
|
||||
CHECK(test_runner::_memory_fail_triggered); \
|
||||
test_runner::_memory_fail_triggered = false; \
|
||||
} while (test_runner::_memory_fail_triggered)
|
||||
#else
|
||||
#define CHECK_ALLOC_FAIL(code) do { CHECK(!test_runner::_memory_fail_triggered); try { code; } catch (std::bad_alloc&) {} CHECK(test_runner::_memory_fail_triggered); test_runner::_memory_fail_triggered = false; } while (test_runner::_memory_fail_triggered)
|
||||
#define CHECK_ALLOC_FAIL(code) \
|
||||
do \
|
||||
{ \
|
||||
CHECK(!test_runner::_memory_fail_triggered); \
|
||||
try \
|
||||
{ \
|
||||
code; \
|
||||
} \
|
||||
catch (std::bad_alloc&) \
|
||||
{ \
|
||||
} \
|
||||
CHECK(test_runner::_memory_fail_triggered); \
|
||||
test_runner::_memory_fail_triggered = false; \
|
||||
} while (test_runner::_memory_fail_triggered)
|
||||
#endif
|
||||
|
||||
#define STR(text) PUGIXML_TEXT(text)
|
||||
|
@ -161,7 +191,7 @@ struct dummy_fixture {};
|
|||
#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)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -3,9 +3,9 @@
|
|||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
@ -70,13 +70,7 @@ TEST_XML(dom_attr_set_value, "<node/>")
|
|||
CHECK(node.append_attribute(STR("attr8")).set_value(true));
|
||||
CHECK(!xml_attribute().set_value(true));
|
||||
|
||||
CHECK(node.append_attribute(STR("attr9")).set_value(STR("v2"), 2));
|
||||
CHECK(!xml_attribute().set_value(STR("v2")));
|
||||
|
||||
CHECK(node.append_attribute(STR("attr10")).set_value(STR("v3foobar"), 2));
|
||||
CHECK(!xml_attribute().set_value(STR("v3")));
|
||||
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" attr9=\"v2\" attr10=\"v3\"/>"));
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\"/>"));
|
||||
}
|
||||
|
||||
#if LONG_MAX > 2147483647
|
||||
|
@ -180,7 +174,7 @@ TEST_XML(dom_attr_assign_large_number_float, "<node attr='' />")
|
|||
node.attribute(STR("attr")) = std::numeric_limits<float>::max();
|
||||
|
||||
CHECK(test_node(node, STR("<node attr=\"3.40282347e+038\"/>"), STR(""), format_raw) ||
|
||||
test_node(node, STR("<node attr=\"3.40282347e+38\"/>"), STR(""), format_raw));
|
||||
test_node(node, STR("<node attr=\"3.40282347e+38\"/>"), STR(""), format_raw));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_assign_large_number_double, "<node attr='' />")
|
||||
|
@ -215,24 +209,6 @@ TEST_XML(dom_node_set_value, "<node>text</node>")
|
|||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_partially_with_size, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text"), 2));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text"), 2));
|
||||
CHECK(!xml_node().set_value(STR("no text"), 2));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_with_size, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text"), 7));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text"), 7));
|
||||
CHECK(!xml_node().set_value(STR("no text"), 7));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_allocated, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text")));
|
||||
|
@ -516,36 +492,6 @@ TEST_XML(dom_node_remove_attribute, "<node a1='v1' a2='v2' a3='v3'><child a4='v4
|
|||
CHECK_NODE(doc, STR("<node a2=\"v2\"><child/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_attributes, "<node a1='v1' a2='v2' a3='v3'><child a4='v4'/></node>")
|
||||
{
|
||||
CHECK(!xml_node().remove_attributes());
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
CHECK(child.remove_attributes());
|
||||
CHECK_NODE(child, STR("<child/>"));
|
||||
|
||||
CHECK(node.remove_attributes());
|
||||
CHECK_NODE(node, STR("<node><child/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_attributes_lots, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
// this test makes sure we generate at least 2 pages (64K) worth of attribute data
|
||||
// so that we can trigger page deallocation to make sure code is memory safe
|
||||
for (size_t i = 0; i < 10000; ++i)
|
||||
node.append_attribute(STR("a")) = STR("v");
|
||||
|
||||
CHECK_STRING(node.attribute(STR("a")).value(), STR("v"));
|
||||
|
||||
CHECK(node.remove_attributes());
|
||||
|
||||
CHECK_STRING(node.attribute(STR("a")).value(), STR(""));
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_prepend_child, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().prepend_child() == xml_node());
|
||||
|
@ -761,36 +707,6 @@ TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node
|
|||
CHECK_NODE(doc, STR("<node><n2/><child/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_children, "<node><n1/><n2/><n3/><child><n4/></child></node>")
|
||||
{
|
||||
CHECK(!xml_node().remove_children());
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node child = node.child(STR("child"));
|
||||
|
||||
CHECK(child.remove_children());
|
||||
CHECK_NODE(child, STR("<child/>"));
|
||||
|
||||
CHECK(node.remove_children());
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_children_lots, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
// this test makes sure we generate at least 2 pages (64K) worth of node data
|
||||
// so that we can trigger page deallocation to make sure code is memory safe
|
||||
for (size_t i = 0; i < 10000; ++i)
|
||||
node.append_child().set_name(STR("n"));
|
||||
|
||||
CHECK(node.child(STR("n")));
|
||||
|
||||
CHECK(node.remove_children());
|
||||
|
||||
CHECK(!node.child(STR("n")));
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_child_complex, "<node id='1'><n1 id1='1' id2='2'/><n2/><n3/><child><n4/></child></node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).remove_child(STR("n1")));
|
||||
|
@ -964,12 +880,12 @@ TEST(dom_node_declaration_name)
|
|||
|
||||
TEST(dom_node_declaration_attributes)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_node node = doc.append_child(node_declaration);
|
||||
node.append_attribute(STR("version")) = STR("1.0");
|
||||
node.append_attribute(STR("encoding")) = STR("utf-8");
|
||||
xml_document doc;
|
||||
xml_node node = doc.append_child(node_declaration);
|
||||
node.append_attribute(STR("version")) = STR("1.0");
|
||||
node.append_attribute(STR("encoding")) = STR("utf-8");
|
||||
|
||||
CHECK_NODE(doc, STR("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
|
||||
CHECK_NODE(doc, STR("<?xml version=\"1.0\" encoding=\"utf-8\"?>"));
|
||||
}
|
||||
|
||||
TEST(dom_node_declaration_top_level)
|
||||
|
@ -1010,7 +926,8 @@ TEST(dom_string_out_of_memory)
|
|||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
xml_document doc;
|
||||
|
@ -1060,8 +977,8 @@ TEST(dom_node_out_of_memory)
|
|||
xml_attribute a = n.append_attribute(STR("a"));
|
||||
CHECK(a);
|
||||
|
||||
CHECK_ALLOC_FAIL(while (n.append_child(node_comment)) { /* nop */ });
|
||||
CHECK_ALLOC_FAIL(while (n.append_attribute(STR("b"))) { /* nop */ });
|
||||
CHECK_ALLOC_FAIL(while (n.append_child(node_comment)){/* nop */});
|
||||
CHECK_ALLOC_FAIL(while (n.append_attribute(STR("b"))){/* nop */});
|
||||
|
||||
// verify all node modification operations
|
||||
CHECK_ALLOC_FAIL(CHECK(!n.append_child()));
|
||||
|
@ -1089,7 +1006,8 @@ TEST(dom_node_memory_limit)
|
|||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
test_runner::_memory_fail_threshold = 32768 * 2 + sizeof(string);
|
||||
|
@ -1108,7 +1026,8 @@ TEST(dom_node_memory_limit_pi)
|
|||
const unsigned int length = 65536;
|
||||
static char_t string[length + 1];
|
||||
|
||||
for (unsigned int i = 0; i < length; ++i) string[i] = 'a';
|
||||
for (unsigned int i = 0; i < length; ++i)
|
||||
string[i] = 'a';
|
||||
string[length] = 0;
|
||||
|
||||
test_runner::_memory_fail_threshold = 32768 * 2 + sizeof(string);
|
||||
|
@ -1157,15 +1076,15 @@ TEST(dom_node_doctype_copy)
|
|||
|
||||
TEST(dom_node_doctype_value)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_node node = doc.append_child(node_doctype);
|
||||
xml_document doc;
|
||||
xml_node node = doc.append_child(node_doctype);
|
||||
|
||||
CHECK(node.type() == node_doctype);
|
||||
CHECK_STRING(node.value(), STR(""));
|
||||
CHECK_NODE(node, STR("<!DOCTYPE>"));
|
||||
CHECK(node.type() == node_doctype);
|
||||
CHECK_STRING(node.value(), STR(""));
|
||||
CHECK_NODE(node, STR("<!DOCTYPE>"));
|
||||
|
||||
CHECK(node.set_value(STR("id [ foo ]")));
|
||||
CHECK_NODE(node, STR("<!DOCTYPE id [ foo ]>"));
|
||||
CHECK(node.set_value(STR("id [ foo ]")));
|
||||
CHECK_NODE(node, STR("<!DOCTYPE id [ foo ]>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_buffer_native, "<node>test</node>")
|
||||
|
@ -1196,7 +1115,6 @@ TEST_XML(dom_node_append_buffer_convert, "<node>test</node>")
|
|||
CHECK_NODE(doc, STR("<node>test<n/><n/></node>"));
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(dom_node_append_buffer_remove, "<node>test</node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
@ -1211,15 +1129,21 @@ TEST_XML(dom_node_append_buffer_remove, "<node>test</node>")
|
|||
|
||||
CHECK_NODE(doc, STR("<node>test<child1 id=\"1\"/><child2>text</child2><child3/><child1 id=\"1\"/><child2>text</child2><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child2"))) {}
|
||||
while (node.remove_child(STR("child2")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test<child1 id=\"1\"/><child3/><child1 id=\"1\"/><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child1"))) {}
|
||||
while (node.remove_child(STR("child1")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test<child3/><child3/></node>"));
|
||||
|
||||
while (node.remove_child(STR("child3"))) {}
|
||||
while (node.remove_child(STR("child3")))
|
||||
{
|
||||
}
|
||||
|
||||
CHECK_NODE(doc, STR("<node>test</node>"));
|
||||
|
||||
|
@ -1749,7 +1673,8 @@ TEST(dom_node_copy_declaration_empty_name)
|
|||
CHECK_STRING(decl2.name(), STR(""));
|
||||
}
|
||||
|
||||
template <typename T> bool fp_equal(T lhs, T rhs)
|
||||
template <typename T>
|
||||
bool fp_equal(T lhs, T rhs)
|
||||
{
|
||||
// Several compilers compare float/double values on x87 stack without proper rounding
|
||||
// This causes roundtrip tests to fail, although they correctly preserve the data.
|
||||
|
@ -1786,39 +1711,14 @@ TEST(dom_fp_roundtrip_min_max_double)
|
|||
CHECK(fp_equal(node.text().as_double(), std::numeric_limits<double>::max()));
|
||||
}
|
||||
|
||||
TEST(dom_fp_double_custom_precision)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_node node = doc.append_child(STR("node"));
|
||||
xml_attribute attr = node.append_attribute(STR("attr"));
|
||||
|
||||
attr.set_value(std::numeric_limits<double>::min(), 20);
|
||||
CHECK(fp_equal(attr.as_double(), std::numeric_limits<double>::min()));
|
||||
|
||||
attr.set_value(1.0f, 5);
|
||||
CHECK(fp_equal(attr.as_double(), static_cast<double>(1.0f)));
|
||||
|
||||
attr.set_value(3.1415926f, 3);
|
||||
CHECK(!fp_equal(attr.as_double(), static_cast<double>(3.1415926f)));
|
||||
|
||||
node.text().set(1.0f, 5);
|
||||
CHECK(fp_equal(node.text().as_double(), static_cast<double>(1.0f)));
|
||||
|
||||
node.text().set(3.1415926f, 3);
|
||||
CHECK(!fp_equal(node.text().as_double(), static_cast<double>(3.1415926f)));
|
||||
|
||||
node.text().set(std::numeric_limits<double>::max(), 20);
|
||||
CHECK(fp_equal(node.text().as_double(), std::numeric_limits<double>::max()));
|
||||
}
|
||||
|
||||
const double fp_roundtrip_base[] =
|
||||
{
|
||||
0.31830988618379067154,
|
||||
0.43429448190325182765,
|
||||
0.57721566490153286061,
|
||||
0.69314718055994530942,
|
||||
0.70710678118654752440,
|
||||
0.78539816339744830962,
|
||||
{
|
||||
0.31830988618379067154,
|
||||
0.43429448190325182765,
|
||||
0.57721566490153286061,
|
||||
0.69314718055994530942,
|
||||
0.70710678118654752440,
|
||||
0.78539816339744830962,
|
||||
};
|
||||
|
||||
TEST(dom_fp_roundtrip_float)
|
||||
|
@ -1847,17 +1747,17 @@ TEST(dom_fp_roundtrip_double)
|
|||
{
|
||||
for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i)
|
||||
{
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__)
|
||||
#if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__)
|
||||
// Not all runtime libraries guarantee roundtripping for denormals
|
||||
if (e == -1021 && fp_roundtrip_base[i] < 0.5)
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef __DMC__
|
||||
// Digital Mars C does not roundtrip on exactly one combination
|
||||
if (e == -12 && i == 1)
|
||||
continue;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
double value = ldexp(fp_roundtrip_base[i], e);
|
||||
|
||||
|
|
|
@ -8,57 +8,57 @@ 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"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child(STR("a")).text());
|
||||
CHECK(node.child(STR("b")).text());
|
||||
CHECK(!node.child(STR("c")).text());
|
||||
CHECK(!node.child(STR("d")).text());
|
||||
CHECK(!xml_node().text());
|
||||
CHECK(!xml_text());
|
||||
CHECK(node.child(STR("a")).text());
|
||||
CHECK(node.child(STR("b")).text());
|
||||
CHECK(!node.child(STR("c")).text());
|
||||
CHECK(!node.child(STR("d")).text());
|
||||
CHECK(!xml_node().text());
|
||||
CHECK(!xml_text());
|
||||
|
||||
generic_empty_test(node.child(STR("a")).text());
|
||||
generic_empty_test(node.child(STR("a")).text());
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_bool_ops, "<node>foo</node>")
|
||||
{
|
||||
generic_bool_ops_test(doc.child(STR("node")).text());
|
||||
generic_bool_ops_test(doc.child(STR("node")).text());
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_text_get, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK_STRING(node.child(STR("a")).text().get(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).first_child().text().get(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).text().get(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).first_child().text().get(), STR("foo"));
|
||||
|
||||
CHECK_STRING(node.child(STR("b")).text().get(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).last_child().text().get(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).text().get(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).last_child().text().get(), STR("bar"));
|
||||
|
||||
CHECK_STRING(node.child(STR("c")).text().get(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).first_child().text().get(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).text().get(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).first_child().text().get(), STR(""));
|
||||
|
||||
CHECK_STRING(node.child(STR("d")).text().get(), STR(""));
|
||||
CHECK_STRING(node.child(STR("d")).text().get(), STR(""));
|
||||
|
||||
CHECK_STRING(xml_node().text().get(), STR(""));
|
||||
CHECK_STRING(xml_node().text().get(), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_text_as_string, "<node><a>foo</a><b><node/><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK_STRING(node.child(STR("a")).text().as_string(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).first_child().text().as_string(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).text().as_string(), STR("foo"));
|
||||
CHECK_STRING(node.child(STR("a")).first_child().text().as_string(), STR("foo"));
|
||||
|
||||
CHECK_STRING(node.child(STR("b")).text().as_string(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).last_child().text().as_string(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).text().as_string(), STR("bar"));
|
||||
CHECK_STRING(node.child(STR("b")).last_child().text().as_string(), STR("bar"));
|
||||
|
||||
CHECK_STRING(node.child(STR("c")).text().as_string(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).first_child().text().as_string(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).text().as_string(), STR(""));
|
||||
CHECK_STRING(node.child(STR("c")).first_child().text().as_string(), STR(""));
|
||||
|
||||
CHECK_STRING(node.child(STR("d")).text().as_string(), STR(""));
|
||||
CHECK_STRING(node.child(STR("d")).text().as_string(), STR(""));
|
||||
|
||||
CHECK_STRING(xml_node().text().as_string(), STR(""));
|
||||
CHECK_STRING(xml_node().text().as_string(), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_int, "<node><text1>1</text1><text2>-1</text2><text3>-2147483648</text3><text4>2147483647</text4><text5>0</text5></node>")
|
||||
|
@ -70,19 +70,19 @@ TEST_XML(dom_text_as_int, "<node><text1>1</text1><text2>-1</text2><text3>-214748
|
|||
CHECK(node.child(STR("text2")).text().as_int() == -1);
|
||||
CHECK(node.child(STR("text3")).text().as_int() == -2147483647 - 1);
|
||||
CHECK(node.child(STR("text4")).text().as_int() == 2147483647);
|
||||
CHECK(node.child(STR("text5")).text().as_int() == 0);
|
||||
CHECK(node.child(STR("text5")).text().as_int() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_int_hex, "<node><text1>0777</text1><text2>0x5ab</text2><text3>0XFf</text3><text4>-0x20</text4><text5>-0x80000000</text5><text6>0x</text6></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child(STR("text1")).text().as_int() == 777); // no octal support! intentional
|
||||
CHECK(node.child(STR("text2")).text().as_int() == 1451);
|
||||
CHECK(node.child(STR("text3")).text().as_int() == 255);
|
||||
CHECK(node.child(STR("text4")).text().as_int() == -32);
|
||||
CHECK(node.child(STR("text5")).text().as_int() == -2147483647 - 1);
|
||||
CHECK(node.child(STR("text6")).text().as_int() == 0);
|
||||
CHECK(node.child(STR("text1")).text().as_int() == 777); // no octal support! intentional
|
||||
CHECK(node.child(STR("text2")).text().as_int() == 1451);
|
||||
CHECK(node.child(STR("text3")).text().as_int() == 255);
|
||||
CHECK(node.child(STR("text4")).text().as_int() == -32);
|
||||
CHECK(node.child(STR("text5")).text().as_int() == -2147483647 - 1);
|
||||
CHECK(node.child(STR("text6")).text().as_int() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_uint, "<node><text1>0</text1><text2>1</text2><text3>2147483647</text3><text4>4294967295</text4><text5>0</text5></node>")
|
||||
|
@ -94,29 +94,29 @@ TEST_XML(dom_text_as_uint, "<node><text1>0</text1><text2>1</text2><text3>2147483
|
|||
CHECK(node.child(STR("text2")).text().as_uint() == 1);
|
||||
CHECK(node.child(STR("text3")).text().as_uint() == 2147483647);
|
||||
CHECK(node.child(STR("text4")).text().as_uint() == 4294967295u);
|
||||
CHECK(node.child(STR("text5")).text().as_uint() == 0);
|
||||
CHECK(node.child(STR("text5")).text().as_uint() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_uint_hex, "<node><text1>0777</text1><text2>0x5ab</text2><text3>0XFf</text3><text4>0x20</text4><text5>0xFFFFFFFF</text5><text6>0x</text6></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child(STR("text1")).text().as_uint() == 777); // no octal support! intentional
|
||||
CHECK(node.child(STR("text2")).text().as_uint() == 1451);
|
||||
CHECK(node.child(STR("text3")).text().as_uint() == 255);
|
||||
CHECK(node.child(STR("text4")).text().as_uint() == 32);
|
||||
CHECK(node.child(STR("text5")).text().as_uint() == 4294967295u);
|
||||
CHECK(node.child(STR("text6")).text().as_uint() == 0);
|
||||
CHECK(node.child(STR("text1")).text().as_uint() == 777); // no octal support! intentional
|
||||
CHECK(node.child(STR("text2")).text().as_uint() == 1451);
|
||||
CHECK(node.child(STR("text3")).text().as_uint() == 255);
|
||||
CHECK(node.child(STR("text4")).text().as_uint() == 32);
|
||||
CHECK(node.child(STR("text5")).text().as_uint() == 4294967295u);
|
||||
CHECK(node.child(STR("text6")).text().as_uint() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_integer_space, "<node><text1> \t\n1234</text1><text2>\n\t 0x123</text2><text3>- 16</text3><text4>- 0x10</text4></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child(STR("text1")).text().as_int() == 1234);
|
||||
CHECK(node.child(STR("text2")).text().as_int() == 291);
|
||||
CHECK(node.child(STR("text3")).text().as_int() == 0);
|
||||
CHECK(node.child(STR("text4")).text().as_int() == 0);
|
||||
CHECK(node.child(STR("text1")).text().as_int() == 1234);
|
||||
CHECK(node.child(STR("text2")).text().as_int() == 291);
|
||||
CHECK(node.child(STR("text3")).text().as_int() == 0);
|
||||
CHECK(node.child(STR("text4")).text().as_int() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
|
||||
|
@ -124,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(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);
|
||||
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);
|
||||
}
|
||||
|
||||
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>")
|
||||
|
@ -211,82 +211,42 @@ TEST_XML(dom_text_as_ullong_hex, "<node><text1>0777</text1><text2>0x5ab</text2><
|
|||
|
||||
TEST_XML(dom_text_get_no_state, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
CHECK(!t);
|
||||
CHECK(t.get() && *t.get() == 0);
|
||||
CHECK(!node.first_child());
|
||||
CHECK(!t);
|
||||
CHECK(t.get() && *t.get() == 0);
|
||||
CHECK(!node.first_child());
|
||||
|
||||
node.append_child(node_pcdata);
|
||||
node.append_child(node_pcdata);
|
||||
|
||||
CHECK(t);
|
||||
CHECK_STRING(t.get(), STR(""));
|
||||
CHECK(t);
|
||||
CHECK_STRING(t.get(), STR(""));
|
||||
|
||||
node.first_child().set_value(STR("test"));
|
||||
node.first_child().set_value(STR("test"));
|
||||
|
||||
CHECK(t);
|
||||
CHECK_STRING(t.get(), STR("test"));
|
||||
CHECK(t);
|
||||
CHECK_STRING(t.get(), STR("test"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_set, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
t.set(STR(""));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node></node>"));
|
||||
t.set(STR(""));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node></node>"));
|
||||
|
||||
t.set(STR("boo"));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>boo</node>"));
|
||||
t.set(STR("boo"));
|
||||
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"));
|
||||
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_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>"));
|
||||
t.set(STR("foobarfoobar"));
|
||||
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_assign, "<node/>")
|
||||
|
@ -439,49 +399,49 @@ TEST_XML(dom_text_set_value_llong, "<node/>")
|
|||
|
||||
TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
CHECK_STRING(t.get(), STR("text"));
|
||||
t.set(STR("notext"));
|
||||
CHECK_STRING(t.get(), STR("text"));
|
||||
t.set(STR("notext"));
|
||||
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2/></node>"));
|
||||
CHECK(node.remove_child(t.data()));
|
||||
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(!t);
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/></node>"));
|
||||
|
||||
t.set(STR("yestext"));
|
||||
t.set(STR("yestext"));
|
||||
|
||||
CHECK(t);
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/>yestext</node>"));
|
||||
CHECK(t.data() == node.last_child());
|
||||
CHECK(t);
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/>yestext</node>"));
|
||||
CHECK(t.data() == node.last_child());
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(dom_text_data, "<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"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.child(STR("a")).text().data() == node.child(STR("a")).first_child());
|
||||
CHECK(node.child(STR("b")).text().data() == node.child(STR("b")).first_child());
|
||||
CHECK(!node.child(STR("c")).text().data());
|
||||
CHECK(!node.child(STR("d")).text().data());
|
||||
CHECK(!xml_text().data());
|
||||
CHECK(node.child(STR("a")).text().data() == node.child(STR("a")).first_child());
|
||||
CHECK(node.child(STR("b")).text().data() == node.child(STR("b")).first_child());
|
||||
CHECK(!node.child(STR("c")).text().data());
|
||||
CHECK(!node.child(STR("d")).text().data());
|
||||
CHECK(!xml_text().data());
|
||||
}
|
||||
|
||||
TEST(dom_text_defaults)
|
||||
{
|
||||
xml_text text;
|
||||
xml_text text;
|
||||
|
||||
CHECK_STRING(text.as_string(STR("foo")), STR("foo"));
|
||||
CHECK(text.as_int(42) == 42);
|
||||
CHECK(text.as_uint(42) == 42);
|
||||
CHECK(text.as_double(42) == 42);
|
||||
CHECK(text.as_float(42) == 42);
|
||||
CHECK(text.as_bool(true) == true);
|
||||
CHECK_STRING(text.as_string(STR("foo")), STR("foo"));
|
||||
CHECK(text.as_int(42) == 42);
|
||||
CHECK(text.as_uint(42) == 42);
|
||||
CHECK(text.as_double(42) == 42);
|
||||
CHECK(text.as_float(42) == 42);
|
||||
CHECK(text.as_bool(true) == true);
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
CHECK(text.as_llong(42) == 42);
|
||||
CHECK(text.as_ullong(42) == 42);
|
||||
CHECK(text.as_llong(42) == 42);
|
||||
CHECK(text.as_ullong(42) == 42);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -4,28 +4,34 @@
|
|||
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "helpers.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
#ifdef PUGIXML_NO_STL
|
||||
template <typename I> static I move_iter(I base, int n)
|
||||
template <typename I>
|
||||
static I move_iter(I base, int n)
|
||||
{
|
||||
if (n > 0) while (n--) ++base;
|
||||
else while (n++) --base;
|
||||
if (n > 0)
|
||||
while (n--)
|
||||
++base;
|
||||
else
|
||||
while (n++)
|
||||
--base;
|
||||
return base;
|
||||
}
|
||||
#else
|
||||
template <typename I> static I move_iter(I base, int n)
|
||||
template <typename I>
|
||||
static I move_iter(I base, int n)
|
||||
{
|
||||
std::advance(base, n);
|
||||
return base;
|
||||
|
@ -150,12 +156,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(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);
|
||||
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);
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_as_double, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
|
||||
|
@ -237,18 +243,18 @@ TEST_XML(dom_attr_as_ullong_hex, "<node attr1='0777' attr2='0x5ab' attr3='0XFf'
|
|||
|
||||
TEST(dom_attr_defaults)
|
||||
{
|
||||
xml_attribute attr;
|
||||
xml_attribute attr;
|
||||
|
||||
CHECK_STRING(attr.as_string(STR("foo")), STR("foo"));
|
||||
CHECK(attr.as_int(42) == 42);
|
||||
CHECK(attr.as_uint(42) == 42);
|
||||
CHECK(attr.as_double(42) == 42);
|
||||
CHECK(attr.as_float(42) == 42);
|
||||
CHECK(attr.as_bool(true) == true);
|
||||
CHECK_STRING(attr.as_string(STR("foo")), STR("foo"));
|
||||
CHECK(attr.as_int(42) == 42);
|
||||
CHECK(attr.as_uint(42) == 42);
|
||||
CHECK(attr.as_double(42) == 42);
|
||||
CHECK(attr.as_float(42) == 42);
|
||||
CHECK(attr.as_bool(true) == true);
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
CHECK(attr.as_llong(42) == 42);
|
||||
CHECK(attr.as_ullong(42) == 42);
|
||||
CHECK(attr.as_llong(42) == 42);
|
||||
CHECK(attr.as_ullong(42) == 42);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -339,18 +345,18 @@ TEST_XML(dom_attr_iterator_invalidate, "<node><node1 attr1='0'/><node2 attr1='0'
|
|||
|
||||
TEST_XML(dom_attr_iterator_const, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
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);
|
||||
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")));
|
||||
CHECK(i3 == node.attributes_end());
|
||||
CHECK(*i1 == node.attribute(STR("attr1")));
|
||||
CHECK(*i2 == node.attribute(STR("attr2")));
|
||||
CHECK(i3 == node.attributes_end());
|
||||
|
||||
CHECK_STRING(i1->name(), STR("attr1"));
|
||||
CHECK_STRING(i2->name(), STR("attr2"));
|
||||
CHECK_STRING(i1->name(), STR("attr1"));
|
||||
CHECK_STRING(i2->name(), STR("attr2"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_bool_ops, "<node/>")
|
||||
|
@ -461,18 +467,18 @@ TEST_XML(dom_node_iterator_invalidate, "<node><node1><child1/></node1><node2><ch
|
|||
|
||||
TEST_XML(dom_node_iterator_const, "<node><child1/><child2/></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
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);
|
||||
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")));
|
||||
CHECK(i3 == node.end());
|
||||
CHECK(*i1 == node.child(STR("child1")));
|
||||
CHECK(*i2 == node.child(STR("child2")));
|
||||
CHECK(i3 == node.end());
|
||||
|
||||
CHECK_STRING(i1->name(), STR("child1"));
|
||||
CHECK_STRING(i2->name(), STR("child2"));
|
||||
CHECK_STRING(i1->name(), STR("child1"));
|
||||
CHECK_STRING(i2->name(), STR("child2"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_parent, "<node><child/></node>")
|
||||
|
@ -659,11 +665,13 @@ struct find_predicate_const
|
|||
{
|
||||
bool result;
|
||||
|
||||
find_predicate_const(bool result_): result(result_)
|
||||
find_predicate_const(bool result_)
|
||||
: result(result_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> bool operator()(const T&) const
|
||||
template <typename T>
|
||||
bool operator()(const T&) const
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
@ -673,18 +681,20 @@ struct find_predicate_prefix
|
|||
{
|
||||
const char_t* prefix;
|
||||
|
||||
find_predicate_prefix(const char_t* prefix_): prefix(prefix_)
|
||||
find_predicate_prefix(const char_t* prefix_)
|
||||
: prefix(prefix_)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T> bool operator()(const T& obj) const
|
||||
template <typename T>
|
||||
bool operator()(const T& obj) const
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
// can't use wcsncmp here because of a bug in DMC
|
||||
return std::basic_string<char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
|
||||
#else
|
||||
#else
|
||||
return strncmp(obj.name(), prefix, strlen(prefix)) == 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -782,34 +792,31 @@ TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></
|
|||
CHECK(doc.first_element_by_path(STR("//node")) == doc.child(STR("node")));
|
||||
}
|
||||
|
||||
struct test_walker: xml_tree_walker
|
||||
struct test_walker : xml_tree_walker
|
||||
{
|
||||
std::basic_string<char_t> log;
|
||||
unsigned int call_count;
|
||||
unsigned int stop_count;
|
||||
|
||||
test_walker(unsigned int stop_count_ = 0): call_count(0), stop_count(stop_count_)
|
||||
test_walker(unsigned int stop_count_ = 0)
|
||||
: call_count(0)
|
||||
, stop_count(stop_count_)
|
||||
{
|
||||
}
|
||||
|
||||
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
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wchar_t wbuf[32];
|
||||
std::copy(buf, buf + strlen(buf) + 1, &wbuf[0]);
|
||||
|
||||
return std::basic_string<char_t>(wbuf);
|
||||
#else
|
||||
#else
|
||||
return std::basic_string<char_t>(buf);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool begin(xml_node& node) PUGIXML_OVERRIDE
|
||||
|
@ -940,7 +947,7 @@ TEST_XML_FLAGS(dom_offset_debug, "<?xml?><!DOCTYPE><?pi?><!--comment--><node>pcd
|
|||
|
||||
TEST(dom_offset_debug_encoding)
|
||||
{
|
||||
char buf[] = { 0, '<', 0, 'n', 0, '/', 0, '>' };
|
||||
char buf[] = {0, '<', 0, 'n', 0, '/', 0, '>'};
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(buf, sizeof(buf)));
|
||||
|
@ -984,17 +991,17 @@ TEST_XML(dom_internal_object, "<node attr='value'>value</node>")
|
|||
CHECK(xml_node().internal_object() == 0);
|
||||
CHECK(xml_attribute().internal_object() == 0);
|
||||
|
||||
CHECK(node.internal_object() != 0);
|
||||
CHECK(value.internal_object() != 0);
|
||||
CHECK(node.internal_object() != value.internal_object());
|
||||
CHECK(node.internal_object() != 0);
|
||||
CHECK(value.internal_object() != 0);
|
||||
CHECK(node.internal_object() != value.internal_object());
|
||||
|
||||
CHECK(attr.internal_object() != 0);
|
||||
CHECK(attr.internal_object() != 0);
|
||||
|
||||
xml_node node_copy = node;
|
||||
CHECK(node_copy.internal_object() == node.internal_object());
|
||||
xml_node node_copy = node;
|
||||
CHECK(node_copy.internal_object() == node.internal_object());
|
||||
|
||||
xml_attribute attr_copy = attr;
|
||||
CHECK(attr_copy.internal_object() == attr.internal_object());
|
||||
xml_attribute attr_copy = attr;
|
||||
CHECK(attr_copy.internal_object() == attr.internal_object());
|
||||
}
|
||||
|
||||
TEST_XML(dom_hash_value, "<node attr='value'>value</node>")
|
||||
|
@ -1006,17 +1013,17 @@ TEST_XML(dom_hash_value, "<node attr='value'>value</node>")
|
|||
CHECK(xml_node().hash_value() == 0);
|
||||
CHECK(xml_attribute().hash_value() == 0);
|
||||
|
||||
CHECK(node.hash_value() != 0);
|
||||
CHECK(value.hash_value() != 0);
|
||||
CHECK(node.hash_value() != value.hash_value());
|
||||
CHECK(node.hash_value() != 0);
|
||||
CHECK(value.hash_value() != 0);
|
||||
CHECK(node.hash_value() != value.hash_value());
|
||||
|
||||
CHECK(attr.hash_value() != 0);
|
||||
CHECK(attr.hash_value() != 0);
|
||||
|
||||
xml_node node_copy = node;
|
||||
CHECK(node_copy.hash_value() == node.hash_value());
|
||||
xml_node node_copy = node;
|
||||
CHECK(node_copy.hash_value() == node.hash_value());
|
||||
|
||||
xml_attribute attr_copy = attr;
|
||||
CHECK(attr_copy.hash_value() == attr.hash_value());
|
||||
xml_attribute attr_copy = attr;
|
||||
CHECK(attr_copy.hash_value() == attr.hash_value());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_named_iterator, "<node><node1><child/></node1><node2><child/><child/></node2><node3/><node4><child/><x/></node4></node>")
|
||||
|
@ -1126,15 +1133,15 @@ TEST_XML(dom_ranged_for, "<node attr1='1' attr2='2'><test>3</test><fake>5</fake>
|
|||
{
|
||||
int index = 1;
|
||||
|
||||
for (xml_node n: doc.children())
|
||||
for (xml_node n : doc.children())
|
||||
{
|
||||
for (xml_attribute a: n.attributes())
|
||||
for (xml_attribute a : n.attributes())
|
||||
{
|
||||
CHECK(a.as_int() == index);
|
||||
index++;
|
||||
}
|
||||
|
||||
for (xml_node c: n.children(STR("test")))
|
||||
for (xml_node c : n.children(STR("test")))
|
||||
{
|
||||
CHECK(c.text().as_int() == index);
|
||||
index++;
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
// Tests header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Tests compatibility with iosfwd
|
||||
#include <iosfwd>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iosfwd>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Tests compatibility with iostream
|
||||
#include <iostream>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <iostream>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
// Check header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
// Check header guards
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Tests compatibility with string
|
||||
#include <string>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <string>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Tests compatibility with string/iostream
|
||||
#include <string>
|
||||
#include "../src/pugixml.hpp"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "test.hpp"
|
||||
|
||||
#include "writer_string.hpp"
|
||||
#include "allocator.hpp"
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -10,28 +10,28 @@ using namespace pugi;
|
|||
|
||||
namespace
|
||||
{
|
||||
int page_allocs = 0;
|
||||
int page_deallocs = 0;
|
||||
int page_allocs = 0;
|
||||
int page_deallocs = 0;
|
||||
|
||||
bool is_page(size_t size)
|
||||
{
|
||||
return size >= 16384;
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* ptr = memory_allocate(size);
|
||||
page_allocs += is_page(memory_size(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
page_deallocs += is_page(memory_size(ptr));
|
||||
memory_deallocate(ptr);
|
||||
}
|
||||
bool is_page(size_t size)
|
||||
{
|
||||
return size >= 16384;
|
||||
}
|
||||
|
||||
void* allocate(size_t size)
|
||||
{
|
||||
void* ptr = memory_allocate(size);
|
||||
page_allocs += is_page(memory_size(ptr));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr)
|
||||
{
|
||||
page_deallocs += is_page(memory_size(ptr));
|
||||
memory_deallocate(ptr);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(memory_custom_memory_management)
|
||||
{
|
||||
page_allocs = page_deallocs = 0;
|
||||
|
@ -116,7 +116,7 @@ TEST(memory_large_allocations)
|
|||
}
|
||||
|
||||
// prune
|
||||
for (node = doc.first_child(); node; )
|
||||
for (node = doc.first_child(); node;)
|
||||
{
|
||||
xml_node next = node.next_sibling().next_sibling();
|
||||
|
||||
|
@ -229,7 +229,8 @@ TEST(memory_string_allocate_decreasing)
|
|||
|
||||
std::basic_string<char_t> s = STR("ab");
|
||||
|
||||
for (int i = 0; i < 17; ++i) s += s;
|
||||
for (int i = 0; i < 17; ++i)
|
||||
s += s;
|
||||
|
||||
for (int j = 0; j < 17; ++j)
|
||||
{
|
||||
|
@ -286,7 +287,8 @@ TEST(memory_string_allocate_decreasing_inplace)
|
|||
|
||||
std::basic_string<char_t> s = STR("ab");
|
||||
|
||||
for (int i = 0; i < 17; ++i) s += s;
|
||||
for (int i = 0; i < 17; ++i)
|
||||
s += s;
|
||||
|
||||
for (int j = 0; j < 17; ++j)
|
||||
{
|
||||
|
|
|
@ -279,132 +279,132 @@ TEST(parse_ws_pcdata_parse)
|
|||
|
||||
static int get_tree_node_count(xml_node n)
|
||||
{
|
||||
int result = 1;
|
||||
int result = 1;
|
||||
|
||||
for (xml_node c = n.first_child(); c; c = c.next_sibling())
|
||||
result += get_tree_node_count(c);
|
||||
for (xml_node c = n.first_child(); c; c = c.next_sibling())
|
||||
result += get_tree_node_count(c);
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
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 char_t* source;
|
||||
const char_t* result;
|
||||
int nodes; // negative if parsing should fail
|
||||
};
|
||||
struct test_data_t
|
||||
{
|
||||
unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
|
||||
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},
|
||||
// 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>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},
|
||||
// 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},
|
||||
// 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},
|
||||
{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},
|
||||
{2, STR("<node> "), STR("<node> </node>"), -3},
|
||||
// error case: terminate PCDATA as early as possible
|
||||
{7, STR("<node>"), STR("<node/>"), -2},
|
||||
{7, STR("<node>a"), STR("<node>a</node>"), -3},
|
||||
{5, STR("<node> "), STR("<node/>"), -2},
|
||||
{2, STR("<node> "), STR("<node> </node>"), -3},
|
||||
};
|
||||
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},
|
||||
// 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>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},
|
||||
// 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},
|
||||
// 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},
|
||||
{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},
|
||||
{2, STR("<node> "), STR("<node> </node>"), -3},
|
||||
// error case: terminate PCDATA as early as possible
|
||||
{7, STR("<node>"), STR("<node/>"), -2},
|
||||
{7, STR("<node>a"), STR("<node>a</node>"), -3},
|
||||
{5, STR("<node> "), STR("<node/>"), -2},
|
||||
{2, STR("<node> "), STR("<node> </node>"), -3},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
|
||||
for (int flag = 0; flag < 3; ++flag)
|
||||
{
|
||||
if (td.mask & (1 << flag))
|
||||
{
|
||||
unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
|
||||
for (int flag = 0; flag < 3; ++flag)
|
||||
{
|
||||
if (td.mask & (1 << flag))
|
||||
{
|
||||
unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
|
||||
|
||||
xml_document doc;
|
||||
CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag]));
|
||||
CHECK_NODE(doc, td.result);
|
||||
xml_document doc;
|
||||
CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag]));
|
||||
CHECK_NODE(doc, td.result);
|
||||
|
||||
int nodes = get_tree_node_count(doc);
|
||||
CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
int nodes = get_tree_node_count(doc);
|
||||
CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 char_t* source;
|
||||
const char_t* result;
|
||||
int nodes; // negative if parsing should fail
|
||||
};
|
||||
struct test_data_t
|
||||
{
|
||||
unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
|
||||
const char_t* source;
|
||||
const char_t* result;
|
||||
int nodes; // negative if parsing should fail
|
||||
};
|
||||
|
||||
test_data_t test_data[] =
|
||||
{
|
||||
// external pcdata should be preserved
|
||||
{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},
|
||||
};
|
||||
test_data_t test_data[] =
|
||||
{
|
||||
// external pcdata should be preserved
|
||||
{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},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
|
||||
for (int flag = 0; flag < 3; ++flag)
|
||||
{
|
||||
if (td.mask & (1 << flag))
|
||||
{
|
||||
unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
|
||||
for (int flag = 0; flag < 3; ++flag)
|
||||
{
|
||||
if (td.mask & (1 << flag))
|
||||
{
|
||||
unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
|
||||
|
||||
xml_document doc;
|
||||
CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag] | parse_fragment));
|
||||
CHECK_NODE(doc, td.result);
|
||||
xml_document doc;
|
||||
CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag] | parse_fragment));
|
||||
CHECK_NODE(doc, td.result);
|
||||
|
||||
int nodes = get_tree_node_count(doc);
|
||||
CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
int nodes = get_tree_node_count(doc);
|
||||
CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_pcdata_no_eol)
|
||||
|
@ -439,49 +439,48 @@ TEST(parse_pcdata_error)
|
|||
|
||||
TEST(parse_pcdata_trim)
|
||||
{
|
||||
struct test_data_t
|
||||
{
|
||||
const char_t* source;
|
||||
const char_t* result;
|
||||
unsigned int flags;
|
||||
};
|
||||
struct test_data_t
|
||||
{
|
||||
const char_t* source;
|
||||
const char_t* result;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
test_data_t test_data[] =
|
||||
{
|
||||
{ STR("<node> text</node>"), STR("text"), 0 },
|
||||
{ STR("<node>\t\n text</node>"), STR("text"), 0 },
|
||||
{ STR("<node>text </node>"), STR("text"), 0 },
|
||||
{ STR("<node>text \t\n</node>"), STR("text"), 0 },
|
||||
{ STR("<node>\r\n\t text \t\n\r</node>"), STR("text"), 0 },
|
||||
{ STR(" text"), STR("text"), parse_fragment },
|
||||
{ STR("\t\n text"), STR("text"), parse_fragment },
|
||||
{ STR("text "), STR("text"), parse_fragment },
|
||||
{ STR("text \t\n"), STR("text"), parse_fragment },
|
||||
{ STR("\r\n\t text \t\n\r"), STR("text"), parse_fragment },
|
||||
{ STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\r more"), 0 },
|
||||
{ STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\n more"), parse_eol },
|
||||
{ STR("<node>\r\n\t text \r\n\r\n\r\n\r\n\r\n\r\n\r\n more \r\n\t</node>"), STR("text \n\n\n\n\n\n\n more"), parse_eol },
|
||||
{ STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), 0 },
|
||||
{ STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), parse_escapes },
|
||||
{ STR(" test&&&&&&& "), STR("test&&&&&&&"), parse_fragment | parse_escapes },
|
||||
{ STR("<node>\r\n\t text \t\n\r m&&e \r\n\t</node>"), STR("text \t\n\n m&&e"), parse_eol | parse_escapes }
|
||||
};
|
||||
test_data_t test_data[] =
|
||||
{
|
||||
{STR("<node> text</node>"), STR("text"), 0},
|
||||
{STR("<node>\t\n text</node>"), STR("text"), 0},
|
||||
{STR("<node>text </node>"), STR("text"), 0},
|
||||
{STR("<node>text \t\n</node>"), STR("text"), 0},
|
||||
{STR("<node>\r\n\t text \t\n\r</node>"), STR("text"), 0},
|
||||
{STR(" text"), STR("text"), parse_fragment},
|
||||
{STR("\t\n text"), STR("text"), parse_fragment},
|
||||
{STR("text "), STR("text"), parse_fragment},
|
||||
{STR("text \t\n"), STR("text"), parse_fragment},
|
||||
{STR("\r\n\t text \t\n\r"), STR("text"), parse_fragment},
|
||||
{STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\r more"), 0},
|
||||
{STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\n more"), parse_eol},
|
||||
{STR("<node>\r\n\t text \r\n\r\n\r\n\r\n\r\n\r\n\r\n more \r\n\t</node>"), STR("text \n\n\n\n\n\n\n more"), parse_eol},
|
||||
{STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), 0},
|
||||
{STR("<node> test&&&&&&& </node>"), STR("test&&&&&&&"), parse_escapes},
|
||||
{STR(" test&&&&&&& "), STR("test&&&&&&&"), parse_fragment | parse_escapes},
|
||||
{STR("<node>\r\n\t text \t\n\r m&&e \r\n\t</node>"), STR("text \t\n\n m&&e"), parse_eol | parse_escapes}};
|
||||
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
|
||||
{
|
||||
const test_data_t& td = test_data[i];
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(td.source, td.flags | parse_trim_pcdata));
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(td.source, td.flags | parse_trim_pcdata));
|
||||
|
||||
const char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get();
|
||||
CHECK_STRING(value, td.result);
|
||||
}
|
||||
const char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get();
|
||||
CHECK_STRING(value, td.result);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_pcdata_trim_empty)
|
||||
{
|
||||
unsigned int flags[] = { 0, parse_ws_pcdata, parse_ws_pcdata_single, parse_ws_pcdata | parse_ws_pcdata_single };
|
||||
unsigned int flags[] = {0, parse_ws_pcdata, parse_ws_pcdata_single, parse_ws_pcdata | parse_ws_pcdata_single};
|
||||
|
||||
for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
|
||||
{
|
||||
|
@ -696,7 +695,6 @@ TEST(parse_attribute_variations)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(parse_attribute_error)
|
||||
{
|
||||
xml_document doc;
|
||||
|
@ -926,10 +924,10 @@ TEST(parse_out_of_memory_halfway_node)
|
|||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[4*i + 0] = '<';
|
||||
text[4*i + 1] = 'n';
|
||||
text[4*i + 2] = '/';
|
||||
text[4*i + 3] = '>';
|
||||
text[4 * i + 0] = '<';
|
||||
text[4 * i + 1] = 'n';
|
||||
text[4 * i + 2] = '/';
|
||||
text[4 * i + 3] = '>';
|
||||
}
|
||||
|
||||
test_runner::_memory_fail_threshold = 65536;
|
||||
|
@ -949,11 +947,11 @@ TEST(parse_out_of_memory_halfway_attr)
|
|||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[5*i + 2] = ' ';
|
||||
text[5*i + 3] = 'a';
|
||||
text[5*i + 4] = '=';
|
||||
text[5*i + 5] = '"';
|
||||
text[5*i + 6] = '"';
|
||||
text[5 * i + 2] = ' ';
|
||||
text[5 * i + 3] = 'a';
|
||||
text[5 * i + 4] = '=';
|
||||
text[5 * i + 5] = '"';
|
||||
text[5 * i + 6] = '"';
|
||||
}
|
||||
|
||||
text[5 * count + 2] = '/';
|
||||
|
@ -984,10 +982,10 @@ TEST(parse_out_of_memory_allocator_state_sync)
|
|||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
text[4*i + 0] = '<';
|
||||
text[4*i + 1] = 'n';
|
||||
text[4*i + 2] = '/';
|
||||
text[4*i + 3] = '>';
|
||||
text[4 * i + 0] = '<';
|
||||
text[4 * i + 1] = 'n';
|
||||
text[4 * i + 2] = '/';
|
||||
text[4 * i + 3] = '>';
|
||||
}
|
||||
|
||||
test_runner::_memory_fail_threshold = 65536;
|
||||
|
@ -1072,18 +1070,18 @@ TEST(parse_bom_fragment)
|
|||
};
|
||||
|
||||
const test_data_t data[] =
|
||||
{
|
||||
{ encoding_utf8, "\xef\xbb\xbf", 3, STR("") },
|
||||
{ encoding_utf8, "\xef\xbb\xbftest", 7, STR("test") },
|
||||
{ encoding_utf16_be, "\xfe\xff", 2, STR("") },
|
||||
{ encoding_utf16_be, "\xfe\xff\x00t\x00o\x00s\x00t", 10, STR("tost") },
|
||||
{ encoding_utf16_le, "\xff\xfe", 2, STR("") },
|
||||
{ encoding_utf16_le, "\xff\xfet\x00o\x00s\x00t\x00", 10, STR("tost") },
|
||||
{ encoding_utf32_be, "\x00\x00\xfe\xff", 4, STR("") },
|
||||
{ encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, STR("tost") },
|
||||
{ encoding_utf32_le, "\xff\xfe\x00\x00", 4, STR("") },
|
||||
{ encoding_utf32_le, "\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, STR("tost") },
|
||||
};
|
||||
{
|
||||
{encoding_utf8, "\xef\xbb\xbf", 3, STR("")},
|
||||
{encoding_utf8, "\xef\xbb\xbftest", 7, STR("test")},
|
||||
{encoding_utf16_be, "\xfe\xff", 2, STR("")},
|
||||
{encoding_utf16_be, "\xfe\xff\x00t\x00o\x00s\x00t", 10, STR("tost")},
|
||||
{encoding_utf16_le, "\xff\xfe", 2, STR("")},
|
||||
{encoding_utf16_le, "\xff\xfet\x00o\x00s\x00t\x00", 10, STR("tost")},
|
||||
{encoding_utf32_be, "\x00\x00\xfe\xff", 4, STR("")},
|
||||
{encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, STR("tost")},
|
||||
{encoding_utf32_le, "\xff\xfe\x00\x00", 4, STR("")},
|
||||
{encoding_utf32_le, "\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, STR("tost")},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
|
||||
{
|
||||
|
@ -1171,12 +1169,11 @@ TEST(parse_close_tag_eof)
|
|||
TEST(parse_fuzz_doctype)
|
||||
{
|
||||
unsigned char data[] =
|
||||
{
|
||||
0x3b, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0xef, 0xbb, 0xbf, 0x3c, 0x3f, 0x78,
|
||||
0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22,
|
||||
0x3f, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0xe9, 0x80, 0xb1, 0xe5, 0xa0, 0xb1, 0xe3, 0x82, 0xb4,
|
||||
0xe3, 0x83, 0xb3, 0x20, 0xef, 0x83, 0x97, 0xe3, 0xa9, 0x2a, 0x20, 0x2d, 0x2d, 0x3e
|
||||
};
|
||||
{
|
||||
0x3b, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0xef, 0xbb, 0xbf, 0x3c, 0x3f, 0x78,
|
||||
0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22,
|
||||
0x3f, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0xe9, 0x80, 0xb1, 0xe5, 0xa0, 0xb1, 0xe3, 0x82, 0xb4,
|
||||
0xe3, 0x83, 0xb3, 0x20, 0xef, 0x83, 0x97, 0xe3, 0xa9, 0x2a, 0x20, 0x2d, 0x2d, 0x3e};
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer(data, sizeof(data)).status == status_bad_doctype);
|
||||
|
@ -1215,9 +1212,9 @@ TEST(parse_embed_pcdata)
|
|||
CHECK_STRING(child.child_value(), STR("outer"));
|
||||
CHECK_STRING(child.child_value(STR("inner2")), STR("value2"));
|
||||
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
#ifndef PUGIXML_NO_XPATH
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(node/child/*[starts-with(., 'value')])"), 2);
|
||||
#endif
|
||||
#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);
|
||||
|
@ -1286,23 +1283,23 @@ TEST(parse_encoding_detect_auto)
|
|||
};
|
||||
|
||||
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 },
|
||||
};
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
@ -1324,27 +1321,27 @@ TEST(parse_encoding_detect_auto_incomplete)
|
|||
};
|
||||
|
||||
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 },
|
||||
};
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include "test.hpp"
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <string>
|
||||
#include <wchar.h>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
@ -30,21 +30,28 @@ static bool test_doctype_wf(const char_t* decl)
|
|||
xml_document doc;
|
||||
|
||||
// standalone
|
||||
if (!load_concat(doc, decl) || !doc.first_child().empty()) return false;
|
||||
if (!load_concat(doc, decl) || !doc.first_child().empty())
|
||||
return false;
|
||||
|
||||
// pcdata pre/postfix
|
||||
if (!load_concat(doc, STR("a"), decl) || !test_node(doc, STR("a"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, decl, STR("b")) || !test_node(doc, STR("b"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("a"), decl, STR("b")) || !test_node(doc, STR("ab"), STR(""), format_raw)) return false;
|
||||
if (!load_concat(doc, STR("a"), decl) || !test_node(doc, STR("a"), STR(""), format_raw))
|
||||
return false;
|
||||
if (!load_concat(doc, decl, STR("b")) || !test_node(doc, STR("b"), STR(""), format_raw))
|
||||
return false;
|
||||
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));
|
||||
CHECK_NODE(doc, decl);
|
||||
// check load-store contents preservation
|
||||
CHECK(doc.load_string(decl, parse_doctype | parse_fragment));
|
||||
CHECK_NODE(doc, decl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -54,13 +61,16 @@ static bool test_doctype_nwf(const char_t* decl)
|
|||
xml_document doc;
|
||||
|
||||
// standalone
|
||||
if (load_concat(doc, decl).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
// pcdata postfix
|
||||
if (load_concat(doc, decl, STR("b")).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl, STR("b")).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
// node postfix
|
||||
if (load_concat(doc, decl, STR("<nodeb/>")).status != status_bad_doctype) return false;
|
||||
if (load_concat(doc, decl, STR("<nodeb/>")).status != status_bad_doctype)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -221,7 +231,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)> <!--* Missing Name S contentspec in elementdecl *--> <!ELEMENT > ]>");
|
||||
TEST_DOCTYPE_WF("<!DOCTYPE root [ <!ELEMENT root (#PCDATA)> <!--* Mising 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> ]>");
|
||||
|
@ -281,9 +291,9 @@ TEST(parse_doctype_xmlconf_oasis_1)
|
|||
TEST_DOCTYPE_WF("<!DOCTYPE doc [ <!ELEMENT doc EMPTY> <!NOTATION not1 PUBLIC \"a b cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\"> <!NOTATION not2 PUBLIC '0123456789-()+,./:=?;!*#@$_%'> <!NOTATION not3 PUBLIC \"0123456789-()+,.'/:=?;!*#@$_%\"> ]>");
|
||||
TEST_DOCTYPE_WF("<!DOCTYPE doc SYSTEM \"p31pass1.dtd\" [<!ELEMENT doc EMPTY>]>");
|
||||
|
||||
// not actually a doctype :)
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(STR("<!--a <!DOCTYPE <?- ]]>-<[ CDATA [ \"- -'- -<doc>--> <!---->"), parse_full | parse_fragment) && doc.first_child().type() == node_comment && doc.last_child().type() == node_comment && doc.first_child().next_sibling() == doc.last_child());
|
||||
// not actually a doctype :)
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(STR("<!--a <!DOCTYPE <?- ]]>-<[ CDATA [ \"- -'- -<doc>--> <!---->"), parse_full | parse_fragment) && doc.first_child().type() == node_comment && doc.last_child().type() == node_comment && doc.first_child().next_sibling() == doc.last_child());
|
||||
CHECK(doc.load_string(STR("<?xmla <!DOCTYPE <[ CDATA [</doc> &a%b&#c?>"), parse_full | parse_fragment) && doc.first_child().type() == node_pi && doc.first_child() == doc.last_child());
|
||||
}
|
||||
|
||||
|
@ -303,22 +313,22 @@ TEST(parse_doctype_xmlconf_xmltest_1)
|
|||
|
||||
TEST_XML_FLAGS(parse_doctype_value, "<!DOCTYPE doc [ <!ELEMENT doc (#PCDATA)> <!ENTITY e \"<![CDATA[Tim & Michael]]>\"> ]>", parse_fragment | parse_doctype)
|
||||
{
|
||||
xml_node n = doc.first_child();
|
||||
xml_node n = doc.first_child();
|
||||
|
||||
CHECK(n.type() == node_doctype);
|
||||
CHECK_STRING(n.value(), STR("doc [ <!ELEMENT doc (#PCDATA)> <!ENTITY e \"<![CDATA[Tim & Michael]]>\"> ]"));
|
||||
CHECK(n.type() == node_doctype);
|
||||
CHECK_STRING(n.value(), STR("doc [ <!ELEMENT doc (#PCDATA)> <!ENTITY e \"<![CDATA[Tim & Michael]]>\"> ]"));
|
||||
}
|
||||
|
||||
TEST(parse_doctype_error_toplevel)
|
||||
{
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(STR("<node><!DOCTYPE></node>")).status == status_bad_doctype);
|
||||
CHECK(doc.load_string(STR("<node><!DOCTYPE></node>"), parse_doctype).status == status_bad_doctype);
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(STR("<node><!DOCTYPE></node>")).status == status_bad_doctype);
|
||||
CHECK(doc.load_string(STR("<node><!DOCTYPE></node>"), parse_doctype).status == status_bad_doctype);
|
||||
}
|
||||
|
||||
TEST(parse_doctype_error_ignore)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ ")).status == status_bad_doctype);
|
||||
CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ "), parse_doctype).status == status_bad_doctype);
|
||||
CHECK(doc.load_string(STR("<!DOCTYPE root [ <![IGNORE[ <![INCLUDE[")).status == status_bad_doctype);
|
||||
|
|
|
@ -73,9 +73,9 @@ TEST(as_wide_invalid)
|
|||
|
||||
TEST(as_wide_string)
|
||||
{
|
||||
std::string s = "abcd";
|
||||
std::string s = "abcd";
|
||||
|
||||
CHECK(as_wide(s) == L"abcd");
|
||||
CHECK(as_wide(s) == L"abcd");
|
||||
}
|
||||
|
||||
TEST(as_utf8_empty)
|
||||
|
@ -110,11 +110,11 @@ TEST(as_utf8_valid_astral)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"\uda1d\ude24 \udbc0\udfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"\xda1d\xde24 \xdbc0\xdfff") == "\xf2\x97\x98\xa4 \xf4\x80\x8f\xbf");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,29 +125,29 @@ TEST(as_utf8_invalid)
|
|||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\uda1d") == "a");
|
||||
CHECK(as_utf8(L"a\uda1d_") == "a_");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xda1d") == "a");
|
||||
CHECK(as_utf8(L"a\xda1d_") == "a_");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(as_utf8(L"a\ude24") == "a");
|
||||
CHECK(as_utf8(L"a\ude24_") == "a_");
|
||||
#else
|
||||
#else
|
||||
CHECK(as_utf8(L"a\xde24") == "a");
|
||||
CHECK(as_utf8(L"a\xde24_") == "a_");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST(as_utf8_string)
|
||||
{
|
||||
std::basic_string<wchar_t> s = L"abcd";
|
||||
std::basic_string<wchar_t> s = L"abcd";
|
||||
|
||||
CHECK(as_utf8(s) == "abcd");
|
||||
CHECK(as_utf8(s) == "abcd");
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "../src/pugixml.hpp"
|
||||
|
||||
#if PUGIXML_VERSION != 1130
|
||||
#if PUGIXML_VERSION != 190
|
||||
#error Unexpected pugixml version
|
||||
#endif
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include "writer_string.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
@ -193,33 +193,17 @@ 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=\"<>'"& 	\"><>'\"&\r\n\t</node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node attr='<>'\"& 	'><>'\"&\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=\"<>'"& 	\"><>'\"&\n\t</node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node attr='<>'\"& 	'><>'\"&\n\t</node>"), STR(""), format_raw | format_attribute_single_quote);
|
||||
CHECK_NODE(doc, STR("<node attr=\"<>'"& \t\"><>'\"&\r\n\t</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(write_escape_unicode, "<node attr='㰀'/>")
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef U_LITERALS
|
||||
CHECK_NODE(doc, STR("<node attr=\"\u3c00\"/>"));
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\x3c00\"/>"));
|
||||
#endif
|
||||
#ifdef U_LITERALS
|
||||
CHECK_NODE(doc, STR("<node attr=\"\u3c00\"/>"));
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\x3c00\"/>"));
|
||||
#endif
|
||||
#else
|
||||
CHECK_NODE(doc, STR("<node attr=\"\xe3\xb0\x80\"/>"));
|
||||
#endif
|
||||
|
@ -233,7 +217,7 @@ TEST_XML(write_no_escapes, "<node attr=''>text</node>")
|
|||
CHECK_NODE_EX(doc, STR("<node attr=\"<>'\"&\x04\r\n\t\"><>'\"&\x04\r\n\t</node>"), STR(""), format_raw | format_no_escapes);
|
||||
}
|
||||
|
||||
struct test_writer: xml_writer
|
||||
struct test_writer : xml_writer
|
||||
{
|
||||
std::basic_string<char_t> contents;
|
||||
|
||||
|
@ -318,7 +302,7 @@ TEST(write_encodings)
|
|||
CHECK(v.size() == 10 && v[0] == '<' && v[1] == 0x54 && v[2] == 0xA2 && v[3] == 0x20AC && v[4] == wchar_cast(0xd852) && v[5] == wchar_cast(0xdf62) && v[6] == ' ' && v[7] == '/' && v[8] == '>' && v[9] == '\n');
|
||||
}
|
||||
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_latin1, "<\x54\xA2?? />\n", 9));
|
||||
CHECK(test_write_narrow(doc, format_default, encoding_latin1, "<\x54\xA2?? />\n", 9));
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
|
@ -329,7 +313,8 @@ TEST(write_encoding_huge)
|
|||
// make a large utf16 name consisting of 6-byte char pairs (6 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf16 += "\x20\xAC\xd8\x52\xdf\x62";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf16 += "\x20\xAC\xd8\x52\xdf\x62";
|
||||
|
||||
s_utf16 += std::string("\x00/\x00>", 4);
|
||||
|
||||
|
@ -338,7 +323,8 @@ TEST(write_encoding_huge)
|
|||
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf8 += "\xE2\x82\xAC\xF0\xA4\xAD\xA2";
|
||||
for (unsigned int j = 0; j < N; ++j)
|
||||
s_utf8 += "\xE2\x82\xAC\xF0\xA4\xAD\xA2";
|
||||
|
||||
s_utf8 += " />\n";
|
||||
|
||||
|
@ -356,7 +342,8 @@ TEST(write_encoding_huge_invalid)
|
|||
// make a large utf16 name consisting of leading surrogate chars
|
||||
std::basic_string<wchar_t> s_utf16;
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf16 += static_cast<wchar_t>(0xd852);
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf16 += static_cast<wchar_t>(0xd852);
|
||||
|
||||
xml_document doc;
|
||||
doc.append_child().set_name(s_utf16.c_str());
|
||||
|
@ -372,7 +359,8 @@ TEST(write_encoding_huge)
|
|||
// make a large utf8 name consisting of 3-byte chars (3 does not divide internal buffer size, so will need split correction)
|
||||
std::string s_utf8 = "<";
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\xE2\x82\xAC";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf8 += "\xE2\x82\xAC";
|
||||
|
||||
s_utf8 += "/>";
|
||||
|
||||
|
@ -381,7 +369,8 @@ TEST(write_encoding_huge)
|
|||
|
||||
std::string s_utf16 = std::string("\x00<", 2);
|
||||
|
||||
for (unsigned int j = 0; j < N; ++j) s_utf16 += "\x20\xAC";
|
||||
for (unsigned int j = 0; j < N; ++j)
|
||||
s_utf16 += "\x20\xAC";
|
||||
|
||||
s_utf16 += std::string("\x00 \x00/\x00>\x00\n", 8);
|
||||
|
||||
|
@ -395,7 +384,8 @@ TEST(write_encoding_huge_invalid)
|
|||
// make a large utf8 name consisting of non-leading chars
|
||||
std::string s_utf8;
|
||||
|
||||
for (unsigned int i = 0; i < N; ++i) s_utf8 += "\x82";
|
||||
for (unsigned int i = 0; i < N; ++i)
|
||||
s_utf8 += "\x82";
|
||||
|
||||
xml_document doc;
|
||||
doc.append_child().set_name(s_utf8.c_str());
|
||||
|
@ -432,22 +422,22 @@ TEST(write_unicode_invalid_utf16)
|
|||
if (wcharsize == 2)
|
||||
{
|
||||
// check non-terminated degenerate handling
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\uda1d_", "a_"));
|
||||
#else
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xda1d_", "a_"));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check incorrect leading code
|
||||
#ifdef U_LITERALS
|
||||
#ifdef U_LITERALS
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\ude24_", "a_"));
|
||||
#else
|
||||
#else
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24", "a"));
|
||||
CHECK(test_write_unicode_invalid(L"a\xde24_", "a_"));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
@ -585,19 +575,17 @@ TEST(write_pcdata_whitespace_fixedpoint)
|
|||
const char_t* data = STR("<node> test <child>\n <sub/>\n </child>\n</node>");
|
||||
|
||||
static const unsigned int flags_parse[] =
|
||||
{
|
||||
0,
|
||||
parse_ws_pcdata,
|
||||
parse_ws_pcdata_single,
|
||||
parse_trim_pcdata
|
||||
};
|
||||
{
|
||||
0,
|
||||
parse_ws_pcdata,
|
||||
parse_ws_pcdata_single,
|
||||
parse_trim_pcdata};
|
||||
|
||||
static const unsigned int flags_format[] =
|
||||
{
|
||||
0,
|
||||
format_raw,
|
||||
format_indent
|
||||
};
|
||||
{
|
||||
0,
|
||||
format_raw,
|
||||
format_indent};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(flags_parse) / sizeof(flags_parse[0]); ++i)
|
||||
{
|
||||
|
@ -634,7 +622,7 @@ TEST_XML(write_no_empty_element_tags, "<node><child1/><child2>text</child2><chil
|
|||
|
||||
TEST_XML_FLAGS(write_roundtrip, "<node><child1 attr1='value1' attr2='value2'/><child2 attr='value'>pre<![CDATA[data]]>mid<text&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 };
|
||||
const unsigned int flagset[] = {format_indent, format_raw, format_no_declaration, format_indent_attributes, format_no_empty_element_tags};
|
||||
size_t flagcount = sizeof(flagset) / sizeof(flagset[0]);
|
||||
|
||||
for (size_t i = 0; i < (size_t(1) << flagcount); ++i)
|
||||
|
@ -685,7 +673,7 @@ TEST(write_flush_coverage)
|
|||
}
|
||||
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
struct throwing_writer: xml_writer
|
||||
struct throwing_writer : xml_writer
|
||||
{
|
||||
virtual void write(const void*, size_t) PUGIXML_OVERRIDE
|
||||
{
|
||||
|
@ -721,13 +709,3 @@ 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>\t\n</a>\n"), STR(""), pugi::format_default);
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
@ -20,27 +20,12 @@ 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");
|
||||
|
||||
for (int i = 0; i < 128; ++i) query += STR("+string-length('abcdefgh')");
|
||||
for (int i = 0; i < 128; ++i)
|
||||
query += STR("+string-length('abcdefgh')");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), query.c_str(), 1024);
|
||||
}
|
||||
|
@ -49,7 +34,8 @@ TEST(xpath_allocator_large_page)
|
|||
{
|
||||
std::basic_string<char_t> query;
|
||||
|
||||
for (int i = 0; i < 1024; ++i) query += STR("abcdefgh");
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
query += STR("abcdefgh");
|
||||
|
||||
CHECK_XPATH_NUMBER(xml_node(), (STR("string-length('") + query + STR("')")).c_str(), 8192);
|
||||
}
|
||||
|
@ -163,51 +149,53 @@ TEST(xpath_sort_random_medium)
|
|||
{
|
||||
xml_document doc;
|
||||
load_document_copy(doc, STR("<node>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("</node>"));
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("</node>"));
|
||||
|
||||
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
|
||||
|
||||
std::vector<xpath_node> nsv(ns.begin(), ns.end());
|
||||
random_shuffle(nsv);
|
||||
std::random_shuffle(nsv.begin(), nsv.end());
|
||||
|
||||
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
|
||||
copy.sort();
|
||||
|
||||
xpath_node_set_tester tester(copy, "sorted order failed");
|
||||
|
||||
for (unsigned int i = 2; i < 39; ++i) tester % i;
|
||||
for (unsigned int i = 2; i < 39; ++i)
|
||||
tester % i;
|
||||
}
|
||||
|
||||
TEST(xpath_sort_random_large)
|
||||
{
|
||||
xml_document doc;
|
||||
load_document_copy(doc, STR("<node>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2></node>"));
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2><child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2>")
|
||||
STR("<child1 attr1='value1' attr2='value2'/><child2 attr1='value1'>test</child2></node>"));
|
||||
|
||||
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
|
||||
|
||||
std::vector<xpath_node> nsv(ns.begin(), ns.end());
|
||||
random_shuffle(nsv);
|
||||
std::random_shuffle(nsv.begin(), nsv.end());
|
||||
|
||||
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
|
||||
copy.sort();
|
||||
|
||||
xpath_node_set_tester tester(copy, "sorted order failed");
|
||||
|
||||
for (unsigned int i = 2; i < 129; ++i) tester % i;
|
||||
for (unsigned int i = 2; i < 129; ++i)
|
||||
tester % i;
|
||||
}
|
||||
|
||||
TEST(xpath_long_numbers_parse)
|
||||
|
@ -221,8 +209,8 @@ TEST(xpath_long_numbers_parse)
|
|||
xml_node c;
|
||||
|
||||
// check parsing
|
||||
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_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_dbl_max, std::numeric_limits<double>::max());
|
||||
CHECK_XPATH_NUMBER(c, str_dbl_max_dec, std::numeric_limits<double>::max());
|
||||
}
|
||||
|
@ -263,7 +251,8 @@ TEST(xpath_denorm_numbers)
|
|||
// 10^-318 - double denormal
|
||||
for (int i = 0; i < 106; ++i)
|
||||
{
|
||||
if (i != 0) query += STR(" * ");
|
||||
if (i != 0)
|
||||
query += STR(" * ");
|
||||
query += STR("0.001");
|
||||
}
|
||||
|
||||
|
@ -298,7 +287,7 @@ TEST_XML(xpath_rexml_2, "<a:x xmlns:a='1'><a:y p='p' q='q'><a:z>zzz</a:z></a:y><
|
|||
TEST_XML(xpath_rexml_3, "<article><section role='subdivision' id='1'><para>free flowing text.</para></section><section role='division'><section role='subdivision' id='2'><para>free flowing text.</para></section><section role='division'><para>free flowing text.</para></section></section></article>")
|
||||
{
|
||||
CHECK_XPATH_NODESET(doc, STR("//section[../self::section[@role=\"division\"]]")) % 10 % 15;
|
||||
CHECK_XPATH_NODESET(doc, STR("//section[@role=\"subdivision\" and not(../self::section[@role=\"division\"])]")) % 3;
|
||||
CHECK_XPATH_NODESET(doc, STR("//section[@role=\"subdivision\" and not(../self::section[@role=\"division\"])]")) % 3;
|
||||
CHECK_XPATH_NODESET(doc, STR("//section[@role=\"subdivision\"][not(../self::section[@role=\"division\"])]")) % 3;
|
||||
}
|
||||
|
||||
|
@ -465,42 +454,15 @@ TEST(xpath_out_of_memory_evaluate_substring)
|
|||
CHECK_ALLOC_FAIL(CHECK(q.evaluate_string(0, 0, xml_node()) == 1));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_out_of_memory_evaluate_union, "<node />")
|
||||
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>")
|
||||
{
|
||||
// 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;
|
||||
test_runner::_memory_fail_threshold = 32768 + 4096 * 2;
|
||||
|
||||
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;
|
||||
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)))))))))))))))))))"));
|
||||
|
||||
CHECK_ALLOC_FAIL(CHECK(q.evaluate_node_set(doc.child(STR("node"))).empty()));
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -759,7 +721,7 @@ TEST(xpath_sort_crossdoc_different_depth)
|
|||
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 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();
|
||||
|
@ -771,9 +733,10 @@ TEST(xpath_allocate_string_out_of_memory)
|
|||
{
|
||||
std::basic_string<char_t> query;
|
||||
|
||||
for (int i = 0; i < 1024; ++i) query += STR("abcdefgh");
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
query += STR("abcdefgh");
|
||||
|
||||
test_runner::_memory_fail_threshold = 8*1024;
|
||||
test_runner::_memory_fail_threshold = 8 * 1024;
|
||||
|
||||
#ifndef __DMC__ // DigitalMars exception handling crashes instead of catching the exception...
|
||||
CHECK_ALLOC_FAIL(CHECK(!xpath_query(query.c_str())));
|
||||
|
|
|
@ -123,7 +123,7 @@ TEST_XML(xpath_api_nodeset_copy, "<node><foo/><foo/></node>")
|
|||
|
||||
xpath_node_set copy3;
|
||||
copy3 = set;
|
||||
copy3 = xpath_node_set(copy3);
|
||||
copy3 = copy3;
|
||||
CHECK(copy3.size() == 2);
|
||||
CHECK_STRING(copy3[0].node().name(), STR("foo"));
|
||||
|
||||
|
@ -141,10 +141,10 @@ TEST_XML(xpath_api_nodeset_copy, "<node><foo/><foo/></node>")
|
|||
|
||||
TEST(xpath_api_nodeset_copy_empty)
|
||||
{
|
||||
xpath_node_set set;
|
||||
xpath_node_set set2 = set;
|
||||
xpath_node_set set3;
|
||||
set3 = set;
|
||||
xpath_node_set set;
|
||||
xpath_node_set set2 = set;
|
||||
xpath_node_set set3;
|
||||
set3 = set;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_evaluate, "<node attr='3'/>")
|
||||
|
@ -430,7 +430,6 @@ TEST_XML(xpath_api_nodeset_move_ctor, "<node><foo/><foo/><bar/></node>")
|
|||
CHECK(move[1] == doc.first_child().first_child());
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_ctor_single, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar"));
|
||||
|
|
|
@ -57,7 +57,7 @@ TEST_XML(xpath_number_sum, "<node>123<child>789</child></node><node/>")
|
|||
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(n, STR("sum(.//node())"), 1701); // 123 + child + 789 = 123 + 789 + 789
|
||||
CHECK_XPATH_NUMBER_NAN(doc.last_child(), STR("sum(.)"));
|
||||
|
||||
// sum with 2 arguments
|
||||
|
@ -423,9 +423,9 @@ TEST(xpath_string_substring_after)
|
|||
|
||||
TEST_XML(xpath_string_substring_after_heap, "<node>foo<child/>bar</node>")
|
||||
{
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'fo')"), STR("obar"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'fooba')"), STR("r"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'foobar')"), STR(""));
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'fo')"), STR("obar"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'fooba')"), STR("r"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring-after(node, 'foobar')"), STR(""));
|
||||
}
|
||||
|
||||
TEST(xpath_string_substring)
|
||||
|
@ -452,7 +452,7 @@ TEST(xpath_string_substring)
|
|||
CHECK_XPATH_STRING(c, STR("substring('abcd', 0 div 0)"), STR(""));
|
||||
CHECK_XPATH_STRING(c, STR("substring('', 1)"), STR(""));
|
||||
CHECK_XPATH_STRING(c, STR("substring('', 0)"), STR(""));
|
||||
CHECK_XPATH_STRING(c, STR("substring(substring('internalexternalcorrect substring',9),9)"), STR("correct substring"));
|
||||
CHECK_XPATH_STRING(c, STR("substring(substring('internalexternalcorrect substring',9),9)"), STR("correct substring"));
|
||||
|
||||
// substring with 3 arguments
|
||||
CHECK_XPATH_STRING(c, STR("substring('abcd', 2, 1)"), STR("b"));
|
||||
|
@ -490,9 +490,9 @@ TEST(xpath_string_substring)
|
|||
|
||||
TEST_XML(xpath_string_substring_heap, "<node>foo<child/>bar</node>")
|
||||
{
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 3)"), STR("obar"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 6)"), STR("r"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 7)"), STR(""));
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 3)"), STR("obar"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 6)"), STR("r"));
|
||||
CHECK_XPATH_STRING(doc, STR("substring(node, 7)"), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_string_string_length, "<node>123</node>")
|
||||
|
@ -590,7 +590,7 @@ TEST_XML(xpath_nodeset_last, "<node><c1/><c1/><c2/><c3/><c3/><c3/><c3/></node>")
|
|||
// last with 0 arguments
|
||||
CHECK_XPATH_NUMBER(n, STR("last()"), 1);
|
||||
CHECK_XPATH_NODESET(n, STR("c1[last() = 1]"));
|
||||
CHECK_XPATH_NODESET(n, STR("c1[last() = 2]")) % 3 % 4; // c1, c1
|
||||
CHECK_XPATH_NODESET(n, STR("c1[last() = 2]")) % 3 % 4; // c1, c1
|
||||
CHECK_XPATH_NODESET(n, STR("c2/preceding-sibling::node()[last() = 2]")) % 4 % 3; // c1, c1
|
||||
|
||||
// last with 1 argument
|
||||
|
@ -829,7 +829,8 @@ TEST(xpath_string_translate_table_out_of_memory)
|
|||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
if (i != 0) query += STR(",");
|
||||
if (i != 0)
|
||||
query += STR(",");
|
||||
query += STR("translate('a','a','A')");
|
||||
}
|
||||
|
||||
|
|
|
@ -194,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 intuitive)
|
||||
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("c3/v != c6/v"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("c1/v != x"), false);
|
||||
CHECK_XPATH_BOOLEAN(n, STR("x != c1/v"), false);
|
||||
|
@ -435,24 +435,6 @@ 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()"));
|
||||
|
|
|
@ -99,82 +99,80 @@ TEST(xpath_semantics_posinv) // coverage for contains()
|
|||
|
||||
TEST(xpath_parse_paths_valid)
|
||||
{
|
||||
const char_t* paths[] =
|
||||
{
|
||||
// From Jaxen tests
|
||||
STR("foo[.='bar']"), STR("foo[.!='bar']"), STR("/"), STR("*"), STR("//foo"), STR("/*"), STR("/."), STR("/foo[/bar[/baz]]"),
|
||||
STR("/foo/bar/baz[(1 or 2) + 3 * 4 + 8 and 9]"), STR("/foo/bar/baz"), STR("(.)[1]"), STR("self::node()"), STR("."), STR("count(/)"),
|
||||
STR("foo[1]"), STR("/baz[(1 or 2) + 3 * 4 + 8 and 9]"), STR("foo/bar[/baz[(1 or 2) - 3 mod 4 + 8 and 9 div 8]]"),
|
||||
STR("foo/bar/yeah:baz[a/b/c and toast]"), STR("/foo/bar[../x='123']"), STR("/foo[@bar='1234']"), STR("foo|bar"),
|
||||
STR("/foo|/bar[@id='1234']"), STR("count(//author/attribute::*)"), STR("/child::node()/child::node()[@id='_13563275']"),
|
||||
STR("10 + (count(descendant::author) * 5)"), STR("10 + count(descendant::author) * 5"), STR("2 + (2 * 5)"), STR("//foo:bar"),
|
||||
STR("count(//author)+5"), STR("count(//author)+count(//author/attribute::*)"), STR("/foo/bar[@a='1' and @c!='2']"),
|
||||
STR("12 + (count(//author)+count(//author/attribute::*)) div 2"), STR("text()[.='foo']"), STR("/*/*[@id='123']")
|
||||
STR("/foo/bar[@a='1' and @b='2']"), STR("/foo/bar[@a='1' and @b!='2']"), STR("//attribute::*[.!='crunchy']"),
|
||||
STR("'//*[contains(string(text()),\"yada yada\")]'"),
|
||||
const char_t* paths[] =
|
||||
{
|
||||
// From Jaxen tests
|
||||
STR("foo[.='bar']"), STR("foo[.!='bar']"), STR("/"), STR("*"), STR("//foo"), STR("/*"), STR("/."), STR("/foo[/bar[/baz]]"),
|
||||
STR("/foo/bar/baz[(1 or 2) + 3 * 4 + 8 and 9]"), STR("/foo/bar/baz"), STR("(.)[1]"), STR("self::node()"), STR("."), STR("count(/)"),
|
||||
STR("foo[1]"), STR("/baz[(1 or 2) + 3 * 4 + 8 and 9]"), STR("foo/bar[/baz[(1 or 2) - 3 mod 4 + 8 and 9 div 8]]"),
|
||||
STR("foo/bar/yeah:baz[a/b/c and toast]"), STR("/foo/bar[../x='123']"), STR("/foo[@bar='1234']"), STR("foo|bar"),
|
||||
STR("/foo|/bar[@id='1234']"), STR("count(//author/attribute::*)"), STR("/child::node()/child::node()[@id='_13563275']"),
|
||||
STR("10 + (count(descendant::author) * 5)"), STR("10 + count(descendant::author) * 5"), STR("2 + (2 * 5)"), STR("//foo:bar"),
|
||||
STR("count(//author)+5"), STR("count(//author)+count(//author/attribute::*)"), STR("/foo/bar[@a='1' and @c!='2']"),
|
||||
STR("12 + (count(//author)+count(//author/attribute::*)) div 2"), STR("text()[.='foo']"), STR("/*/*[@id='123']") STR("/foo/bar[@a='1' and @b='2']"), STR("/foo/bar[@a='1' and @b!='2']"), STR("//attribute::*[.!='crunchy']"),
|
||||
STR("'//*[contains(string(text()),\"yada yada\")]'"),
|
||||
|
||||
// From ajaxslt tests
|
||||
STR("@*"), STR("@*|node()"), STR("/descendant-or-self::div"), STR("/div"), STR("//div"), STR("/descendant-or-self::node()/child::para"),
|
||||
STR("substring('12345', 0, 3)"), STR("//title | //link"), STR("x//title"), STR("x/title"), STR("id('a')//title"), STR("//*[@about]"),
|
||||
STR("count(descendant::*)"), STR("count(descendant::*) + count(ancestor::*)"), STR("@*|text()"), STR("*|/"), STR("source|destination"),
|
||||
STR("page != 'to' and page != 'from'"), STR("substring-after(icon/@image, '/mapfiles/marker')"), STR("substring-before(str, c)"), STR("page = 'from'"),
|
||||
STR("segments/@time"), STR("child::para"), STR("child::*"), STR("child::text()"), STR("child::node()"), STR("attribute::name"), STR("attribute::*"),
|
||||
STR("descendant::para"), STR("ancestor::div"), STR("ancestor-or-self::div"), STR("descendant-or-self::para"), STR("self::para"), STR("child::*/child::para"),
|
||||
STR("concat(substring-before(@image,'marker'),'icon',substring-after(@image,'marker'))"), STR("/"), STR("/descendant::para"), STR("/descendant::olist/child::item"),
|
||||
STR("child::para[position()=1]"), STR("child::para[position()=last()]"), STR("child::para[position()=last()-1]"), STR("child::para[position()>1]"),
|
||||
STR("following-sibling::chapter[position()=1]"), STR("preceding-sibling::chapter[position()=1]"), STR("/descendant::figure[position()=42]"),
|
||||
STR("/child::doc/child::chapter[position()=5]/child::section[position()=2]"), STR("child::chapter/descendant::para"), STR("child::para[attribute::type='warning']"),
|
||||
STR("child::para[attribute::type='warning'][position()=5]"), STR("child::para[position()=5][attribute::type='warning']"), STR("child::chapter[child::title='Introduction']"),
|
||||
STR("child::chapter[child::title]"), STR("child::*[self::chapter or self::appendix]"), STR("child::*[self::chapter or self::appendix][position()=last()]"),
|
||||
STR("count(//*[id='u1']|//*[id='u2'])"), STR("count(//*[id='u1']|//*[class='u'])"), STR("count(//*[class='u']|//*[class='u'])"), STR("count(//*[class='u']|//*[id='u1'])"),
|
||||
STR("count(//*[@id='self']/ancestor-or-self::*)"), STR("count(//*[@id='self']/ancestor::*)"), STR("count(//*[@id='self']/attribute::*)"), STR("count(//*[@id='self']/child::*)"),
|
||||
STR("count(//*[@id='self']/descendant-or-self::*)"), STR("count(//*[@id='self']/descendant::*)"), STR("count(//*[@id='self']/following-sibling::*)"),
|
||||
STR("count(//*[@id='self']/following::*)"), STR("//*[@id='self']/parent::*/@id"), STR("count(//*[@id='self']/preceding-sibling::*)"),
|
||||
STR("count(//*[@id='self']/preceding::*)"), STR("//*[@id='self']/self::*/@id"), STR("id('nested1')/div[1]//input[2]"), STR("id('foo')//div[contains(@id, 'useful')]//input"),
|
||||
STR("(//table[@class='stylee'])//th[text()='theHeaderText']/../td"), STR("address"), STR("address=string(/page/user/defaultlocation)"), STR("count-of-snippet-of-url = 0"),
|
||||
STR("daddr"), STR("form"), STR("form = 'from'"), STR("form = 'to'"), STR("form='near'"), STR("home"), STR("i"), STR("i > page and i < page + range"),
|
||||
STR("i < page and i >= page - range"), STR("i < @max"), STR("i <= page"), STR("i + 1"), STR("i = page"), STR("i = 1"), STR("info = position() or (not(info) and position() = 1)"),
|
||||
STR("is-first-order"), STR("is-first-order and snippets-exist"), STR("more"), STR("more > 0"), STR("near-point"), STR("page"), STR("page != 'from'"), STR("page != 'to'"),
|
||||
STR("page != 'to' and page != 'from'"), STR("page > 1"), STR("page = 'basics'"), STR("page = 'details'"), STR("page = 'from'"), STR("page = 'to'"), STR("page='from'"),
|
||||
STR("page='to'"), STR("r >= 0.5"), STR("r >= 1"), STR("r - 0"), STR("r - 1"), STR("r - 2"), STR("r - 3"), STR("r - 4"), STR("saddr"), STR("sources"), STR("sources[position() < details]"),
|
||||
STR("src"), STR("str"), STR("\"'\""), STR("(//location[string(info/references/reference[1]/url)=string(current-url)]/info/references/reference[1])[1]"),
|
||||
STR("(not(count-of-snippet-of-url = 0) and (position() = 1) or not(current-url = //locations/location[position() = last-pos]//reference[1]/url))"),
|
||||
STR("(not(info) and position() = 1) or info = position()"), STR("."), STR("../@arg0"), STR("../@filterpng"), STR("/page/@filterpng"), STR("4"), STR("@attribution"),
|
||||
STR("@id"), STR("@max > @num"), STR("@meters > 16093"), STR("@name"), STR("@start div @num + 1"), STR("@url"), STR("ad"), STR("address/line"), STR("adsmessage"),
|
||||
STR("attr"), STR("boolean(location[@id='near'][icon/@image])"), STR("bubble/node()"), STR("calltoaction/node()"), STR("category"), STR("contains(str, c)"),
|
||||
STR("count(//location[string(info/references/reference[1]/url)=string(current-url)]//snippet)"), STR("count(//snippet)"), STR("count(attr)"), STR("count(location)"),
|
||||
STR("count(structured/source) > 1"), STR("description/node()"), STR("destination"), STR("destinationAddress"), STR("domain"), STR("false()"), STR("icon/@class != 'noicon'"),
|
||||
STR("icon/@image"), STR("info"), STR("info/address/line"), STR("info/distance"), STR("info/distance and near-point"), STR("info/distance and info/phone and near-point"),
|
||||
STR("info/distance or info/phone"), STR("info/panel/node()"), STR("info/phone"), STR("info/references/reference[1]"), STR("info/references/reference[1]/snippet"),
|
||||
STR("info/references/reference[1]/url"), STR("info/title"), STR("info/title/node()"), STR("line"), STR("location"), STR("location[@id!='near']"), STR("location[@id='near'][icon/@image]"),
|
||||
STR("location[position() > umlocations div 2]"), STR("location[position() <= numlocations div 2]"), STR("locations"), STR("locations/location"), STR("near"), STR("node()"),
|
||||
STR("not(count-of-snippets = 0)"), STR("not(form = 'from')"), STR("not(form = 'near')"), STR("not(form = 'to')"), STR("not(../@page)"), STR("not(structured/source)"), STR("notice"),
|
||||
STR("number(../@info)"), STR("number(../@items)"), STR("number(/page/@linewidth)"), STR("page/ads"), STR("page/directions"), STR("page/error"), STR("page/overlay"),
|
||||
STR("page/overlay/locations/location"), STR("page/refinements"), STR("page/request/canonicalnear"), STR("page/request/near"), STR("page/request/query"), STR("page/spelling/suggestion"),
|
||||
STR("page/user/defaultlocation"), STR("phone"), STR("position()"), STR("position() != 1"), STR("position() != last()"), STR("position() > 1"), STR("position() < details"),
|
||||
STR("position()-1"), STR("query"), STR("references/@total"), STR("references/reference"), STR("references/reference/domain"), STR("references/reference/url"),
|
||||
STR("reviews/@positive div (reviews/@positive + reviews/@negative) * 5"), STR("reviews/@positive div (reviews/@positive + reviews/@negative) * (5)"), STR("reviews/@total"),
|
||||
STR("reviews/@total > 1"), STR("reviews/@total > 5"), STR("reviews/@total = 1"), STR("segments/@distance"), STR("segments/@time"), STR("segments/segment"), STR("shorttitle/node()"),
|
||||
STR("snippet"), STR("snippet/node()"), STR("source"), STR("sourceAddress"), STR("sourceAddress and destinationAddress"), STR("string(../@daddr)"), STR("string(../@form)"),
|
||||
STR("string(../@page)"), STR("string(../@saddr)"), STR("string(info/title)"), STR("string(page/request/canonicalnear) != ''"), STR("string(page/request/near) != ''"),
|
||||
STR("string-length(address) > linewidth"), STR("structured/@total - details"), STR("structured/source"), STR("structured/source[@name]"), STR("substring(address, 1, linewidth - 3)"),
|
||||
STR("substring-after(str, c)"), STR("substring-after(icon/@image, '/mapfiles/marker')"), STR("substring-before(str, c)"), STR("tagline/node()"), STR("targetedlocation"),
|
||||
STR("title"), STR("title/node()"), STR("true()"), STR("url"), STR("visibleurl"), STR("id(\"level10\")/ancestor::SPAN"), STR("id(\"level10\")/ancestor-or-self::SPAN"), STR("//attribute::*"),
|
||||
STR("child::HTML/child::BODY/child::H1"), STR("descendant::node()"), STR("descendant-or-self::SPAN"), STR("id(\"first\")/following::text()"), STR("id(\"first\")/following-sibling::node()"),
|
||||
STR("id(\"level10\")/parent::node()"), STR("id(\"last\")/preceding::text()"), STR("id(\"last\")/preceding-sibling::node()"), STR("/HTML/BODY/H1/self::node()"), STR("//*[@name]"),
|
||||
STR("id(\"pet\")/SELECT[@name=\"species\"]/OPTION[@selected]/@value"), STR("descendant::INPUT[@name=\"name\"]/@value"), STR("id(\"pet\")/INPUT[@name=\"gender\" and @checked]/@value"),
|
||||
STR("//TEXTAREA[@name=\"description\"]/text()"), STR("id(\"div1\")|id(\"div2\")|id(\"div3 div4 div5\")"), STR("//LI[1]"), STR("//LI[last()]/text()"), STR("//LI[position() mod 2]/@class"),
|
||||
STR("//text()[.=\"foo\"]"), STR("descendant-or-self::SPAN[position() > 2]"), STR("descendant::*[contains(@class,\" fruit \")]"),
|
||||
// From ajaxslt tests
|
||||
STR("@*"), STR("@*|node()"), STR("/descendant-or-self::div"), STR("/div"), STR("//div"), STR("/descendant-or-self::node()/child::para"),
|
||||
STR("substring('12345', 0, 3)"), STR("//title | //link"), STR("x//title"), STR("x/title"), STR("id('a')//title"), STR("//*[@about]"),
|
||||
STR("count(descendant::*)"), STR("count(descendant::*) + count(ancestor::*)"), STR("@*|text()"), STR("*|/"), STR("source|destination"),
|
||||
STR("page != 'to' and page != 'from'"), STR("substring-after(icon/@image, '/mapfiles/marker')"), STR("substring-before(str, c)"), STR("page = 'from'"),
|
||||
STR("segments/@time"), STR("child::para"), STR("child::*"), STR("child::text()"), STR("child::node()"), STR("attribute::name"), STR("attribute::*"),
|
||||
STR("descendant::para"), STR("ancestor::div"), STR("ancestor-or-self::div"), STR("descendant-or-self::para"), STR("self::para"), STR("child::*/child::para"),
|
||||
STR("concat(substring-before(@image,'marker'),'icon',substring-after(@image,'marker'))"), STR("/"), STR("/descendant::para"), STR("/descendant::olist/child::item"),
|
||||
STR("child::para[position()=1]"), STR("child::para[position()=last()]"), STR("child::para[position()=last()-1]"), STR("child::para[position()>1]"),
|
||||
STR("following-sibling::chapter[position()=1]"), STR("preceding-sibling::chapter[position()=1]"), STR("/descendant::figure[position()=42]"),
|
||||
STR("/child::doc/child::chapter[position()=5]/child::section[position()=2]"), STR("child::chapter/descendant::para"), STR("child::para[attribute::type='warning']"),
|
||||
STR("child::para[attribute::type='warning'][position()=5]"), STR("child::para[position()=5][attribute::type='warning']"), STR("child::chapter[child::title='Introduction']"),
|
||||
STR("child::chapter[child::title]"), STR("child::*[self::chapter or self::appendix]"), STR("child::*[self::chapter or self::appendix][position()=last()]"),
|
||||
STR("count(//*[id='u1']|//*[id='u2'])"), STR("count(//*[id='u1']|//*[class='u'])"), STR("count(//*[class='u']|//*[class='u'])"), STR("count(//*[class='u']|//*[id='u1'])"),
|
||||
STR("count(//*[@id='self']/ancestor-or-self::*)"), STR("count(//*[@id='self']/ancestor::*)"), STR("count(//*[@id='self']/attribute::*)"), STR("count(//*[@id='self']/child::*)"),
|
||||
STR("count(//*[@id='self']/descendant-or-self::*)"), STR("count(//*[@id='self']/descendant::*)"), STR("count(//*[@id='self']/following-sibling::*)"),
|
||||
STR("count(//*[@id='self']/following::*)"), STR("//*[@id='self']/parent::*/@id"), STR("count(//*[@id='self']/preceding-sibling::*)"),
|
||||
STR("count(//*[@id='self']/preceding::*)"), STR("//*[@id='self']/self::*/@id"), STR("id('nested1')/div[1]//input[2]"), STR("id('foo')//div[contains(@id, 'useful')]//input"),
|
||||
STR("(//table[@class='stylee'])//th[text()='theHeaderText']/../td"), STR("address"), STR("address=string(/page/user/defaultlocation)"), STR("count-of-snippet-of-url = 0"),
|
||||
STR("daddr"), STR("form"), STR("form = 'from'"), STR("form = 'to'"), STR("form='near'"), STR("home"), STR("i"), STR("i > page and i < page + range"),
|
||||
STR("i < page and i >= page - range"), STR("i < @max"), STR("i <= page"), STR("i + 1"), STR("i = page"), STR("i = 1"), STR("info = position() or (not(info) and position() = 1)"),
|
||||
STR("is-first-order"), STR("is-first-order and snippets-exist"), STR("more"), STR("more > 0"), STR("near-point"), STR("page"), STR("page != 'from'"), STR("page != 'to'"),
|
||||
STR("page != 'to' and page != 'from'"), STR("page > 1"), STR("page = 'basics'"), STR("page = 'details'"), STR("page = 'from'"), STR("page = 'to'"), STR("page='from'"),
|
||||
STR("page='to'"), STR("r >= 0.5"), STR("r >= 1"), STR("r - 0"), STR("r - 1"), STR("r - 2"), STR("r - 3"), STR("r - 4"), STR("saddr"), STR("sources"), STR("sources[position() < details]"),
|
||||
STR("src"), STR("str"), STR("\"'\""), STR("(//location[string(info/references/reference[1]/url)=string(current-url)]/info/references/reference[1])[1]"),
|
||||
STR("(not(count-of-snippet-of-url = 0) and (position() = 1) or not(current-url = //locations/location[position() = last-pos]//reference[1]/url))"),
|
||||
STR("(not(info) and position() = 1) or info = position()"), STR("."), STR("../@arg0"), STR("../@filterpng"), STR("/page/@filterpng"), STR("4"), STR("@attribution"),
|
||||
STR("@id"), STR("@max > @num"), STR("@meters > 16093"), STR("@name"), STR("@start div @num + 1"), STR("@url"), STR("ad"), STR("address/line"), STR("adsmessage"),
|
||||
STR("attr"), STR("boolean(location[@id='near'][icon/@image])"), STR("bubble/node()"), STR("calltoaction/node()"), STR("category"), STR("contains(str, c)"),
|
||||
STR("count(//location[string(info/references/reference[1]/url)=string(current-url)]//snippet)"), STR("count(//snippet)"), STR("count(attr)"), STR("count(location)"),
|
||||
STR("count(structured/source) > 1"), STR("description/node()"), STR("destination"), STR("destinationAddress"), STR("domain"), STR("false()"), STR("icon/@class != 'noicon'"),
|
||||
STR("icon/@image"), STR("info"), STR("info/address/line"), STR("info/distance"), STR("info/distance and near-point"), STR("info/distance and info/phone and near-point"),
|
||||
STR("info/distance or info/phone"), STR("info/panel/node()"), STR("info/phone"), STR("info/references/reference[1]"), STR("info/references/reference[1]/snippet"),
|
||||
STR("info/references/reference[1]/url"), STR("info/title"), STR("info/title/node()"), STR("line"), STR("location"), STR("location[@id!='near']"), STR("location[@id='near'][icon/@image]"),
|
||||
STR("location[position() > umlocations div 2]"), STR("location[position() <= numlocations div 2]"), STR("locations"), STR("locations/location"), STR("near"), STR("node()"),
|
||||
STR("not(count-of-snippets = 0)"), STR("not(form = 'from')"), STR("not(form = 'near')"), STR("not(form = 'to')"), STR("not(../@page)"), STR("not(structured/source)"), STR("notice"),
|
||||
STR("number(../@info)"), STR("number(../@items)"), STR("number(/page/@linewidth)"), STR("page/ads"), STR("page/directions"), STR("page/error"), STR("page/overlay"),
|
||||
STR("page/overlay/locations/location"), STR("page/refinements"), STR("page/request/canonicalnear"), STR("page/request/near"), STR("page/request/query"), STR("page/spelling/suggestion"),
|
||||
STR("page/user/defaultlocation"), STR("phone"), STR("position()"), STR("position() != 1"), STR("position() != last()"), STR("position() > 1"), STR("position() < details"),
|
||||
STR("position()-1"), STR("query"), STR("references/@total"), STR("references/reference"), STR("references/reference/domain"), STR("references/reference/url"),
|
||||
STR("reviews/@positive div (reviews/@positive + reviews/@negative) * 5"), STR("reviews/@positive div (reviews/@positive + reviews/@negative) * (5)"), STR("reviews/@total"),
|
||||
STR("reviews/@total > 1"), STR("reviews/@total > 5"), STR("reviews/@total = 1"), STR("segments/@distance"), STR("segments/@time"), STR("segments/segment"), STR("shorttitle/node()"),
|
||||
STR("snippet"), STR("snippet/node()"), STR("source"), STR("sourceAddress"), STR("sourceAddress and destinationAddress"), STR("string(../@daddr)"), STR("string(../@form)"),
|
||||
STR("string(../@page)"), STR("string(../@saddr)"), STR("string(info/title)"), STR("string(page/request/canonicalnear) != ''"), STR("string(page/request/near) != ''"),
|
||||
STR("string-length(address) > linewidth"), STR("structured/@total - details"), STR("structured/source"), STR("structured/source[@name]"), STR("substring(address, 1, linewidth - 3)"),
|
||||
STR("substring-after(str, c)"), STR("substring-after(icon/@image, '/mapfiles/marker')"), STR("substring-before(str, c)"), STR("tagline/node()"), STR("targetedlocation"),
|
||||
STR("title"), STR("title/node()"), STR("true()"), STR("url"), STR("visibleurl"), STR("id(\"level10\")/ancestor::SPAN"), STR("id(\"level10\")/ancestor-or-self::SPAN"), STR("//attribute::*"),
|
||||
STR("child::HTML/child::BODY/child::H1"), STR("descendant::node()"), STR("descendant-or-self::SPAN"), STR("id(\"first\")/following::text()"), STR("id(\"first\")/following-sibling::node()"),
|
||||
STR("id(\"level10\")/parent::node()"), STR("id(\"last\")/preceding::text()"), STR("id(\"last\")/preceding-sibling::node()"), STR("/HTML/BODY/H1/self::node()"), STR("//*[@name]"),
|
||||
STR("id(\"pet\")/SELECT[@name=\"species\"]/OPTION[@selected]/@value"), STR("descendant::INPUT[@name=\"name\"]/@value"), STR("id(\"pet\")/INPUT[@name=\"gender\" and @checked]/@value"),
|
||||
STR("//TEXTAREA[@name=\"description\"]/text()"), STR("id(\"div1\")|id(\"div2\")|id(\"div3 div4 div5\")"), STR("//LI[1]"), STR("//LI[last()]/text()"), STR("//LI[position() mod 2]/@class"),
|
||||
STR("//text()[.=\"foo\"]"), STR("descendant-or-self::SPAN[position() > 2]"), STR("descendant::*[contains(@class,\" fruit \")]"),
|
||||
|
||||
// ajaxslt considers this path invalid, however I believe it's valid as per spec
|
||||
STR("***"),
|
||||
// ajaxslt considers this path invalid, however I believe it's valid as per spec
|
||||
STR("***"),
|
||||
|
||||
// Oasis MSFT considers this path invalid, however I believe it's valid as per spec
|
||||
STR("**..**"),
|
||||
// Oasis MSFT considers this path invalid, however I believe it's valid as per spec
|
||||
STR("**..**"),
|
||||
|
||||
// Miscellaneous
|
||||
STR("..***..***.***.***..***..***..")
|
||||
};
|
||||
// Miscellaneous
|
||||
STR("..***..***.***.***..***..***..")};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
|
@ -185,73 +183,125 @@ TEST(xpath_parse_paths_valid)
|
|||
#if defined(PUGIXML_WCHAR_MODE) || !defined(PUGIXML_NO_STL)
|
||||
TEST(xpath_parse_paths_valid_unicode)
|
||||
{
|
||||
// From ajaxslt
|
||||
// From ajaxslt
|
||||
const wchar_t* paths[] =
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
L"/descendant-or-self::\u90e8\u5206", L"//\u90e8\u5206", L"substring('\uff11\uff12\uff13\uff14\uff15', 0, 3)", L"//\u30bf\u30a4\u30c8\u30eb | //\u30ea\u30f3\u30af",
|
||||
L"\u8b0e//\u30bf\u30a4\u30c8\u30eb", L"//*[@\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3]", L"\u30da\u30fc\u30b8 = '\u304b\u3089'",
|
||||
L"concat(substring-before(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'),'\u30a2\u30a4\u30b3\u30f3',substring-after(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'))",
|
||||
L"\u30bd\u30fc\u30b9|\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3", L"\u30da\u30fc\u30b8 != '\u307e\u3067' and \u30da\u30fc\u30b8 != '\u304b\u3089'",
|
||||
L"substring-after(\u30a2\u30a4\u30b3\u30f3/@\u30a4\u30e1\u30fc\u30b8, '/\u5730\u56f3\u30d5\u30a1\u30a4\u30eb/\u76ee\u5370')", L"child::\u6bb5\u843d",
|
||||
L"substring-before(\u6587\u5b57\u5217, \u6587\u5b57)", L"\u30bb\u30b0\u30e1\u30f3\u30c8/@\u6642\u523b", L"attribute::\u540d\u524d", L"descendant::\u6bb5\u843d",
|
||||
L"ancestor::\u90e8\u5206", L"ancestor-or-self::\u90e8\u5206", L"descendant-or-self::\u6bb5\u843d", L"self::\u6bb5\u843d", L"child::\u7ae0/descendant::\u6bb5\u843d",
|
||||
L"child::*/child::\u6bb5\u843d", L"/descendant::\u6bb5\u843d", L"/descendant::\u9806\u5e8f\u30ea\u30b9\u30c8/child::\u9805\u76ee", L"child::\u6bb5\u843d[position()=1]",
|
||||
L"child::\u6bb5\u843d[position()=last()]", L"child::\u6bb5\u843d[position()=last()-1]", L"child::\u6bb5\u843d[position()>1]", L"following-sibling::\u7ae0[position()=1]",
|
||||
L"preceding-sibling::\u7ae0[position()=1]", L"/descendant::\u56f3\u8868[position()=42]", L"/child::\u6587\u66f8/child::\u7ae0[position()=5]/child::\u7bc0[position()=2]",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']", L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a'][position()=5]",
|
||||
L"child::\u6bb5\u843d[position()=5][attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']", L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb='\u306f\u3058\u3081\u306b']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb]", L"child::*[self::\u7ae0 or self::\u4ed8\u9332]", L"child::*[self::\u7ae0 or self::\u4ed8\u9332][position()=last()]",
|
||||
#else
|
||||
L"/descendant-or-self::\x90e8\x5206", L"//\x90e8\x5206", L"substring('\xff11\xff12\xff13\xff14\xff15', 0, 3)", L"//\x30bf\x30a4\x30c8\x30eb | //\x30ea\x30f3\x30af",
|
||||
L"\x8b0e//\x30bf\x30a4\x30c8\x30eb", L"//*[@\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3]", L"\x30da\x30fc\x30b8 = '\x304b\x3089'",
|
||||
L"concat(substring-before(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'),'\x30a2\x30a4\x30b3\x30f3',substring-after(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'))",
|
||||
L"\x30bd\x30fc\x30b9|\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3", L"\x30da\x30fc\x30b8 != '\x307e\x3067' and \x30da\x30fc\x30b8 != '\x304b\x3089'",
|
||||
L"substring-after(\x30a2\x30a4\x30b3\x30f3/@\x30a4\x30e1\x30fc\x30b8, '/\x5730\x56f3\x30d5\x30a1\x30a4\x30eb/\x76ee\x5370')", L"child::\x6bb5\x843d",
|
||||
L"substring-before(\x6587\x5b57\x5217, \x6587\x5b57)", L"\x30bb\x30b0\x30e1\x30f3\x30c8/@\x6642\x523b", L"attribute::\x540d\x524d", L"descendant::\x6bb5\x843d",
|
||||
L"ancestor::\x90e8\x5206", L"ancestor-or-self::\x90e8\x5206", L"descendant-or-self::\x6bb5\x843d", L"self::\x6bb5\x843d", L"child::\x7ae0/descendant::\x6bb5\x843d",
|
||||
L"child::*/child::\x6bb5\x843d", L"/descendant::\x6bb5\x843d", L"/descendant::\x9806\x5e8f\x30ea\x30b9\x30c8/child::\x9805\x76ee", L"child::\x6bb5\x843d[position()=1]",
|
||||
L"child::\x6bb5\x843d[position()=last()]", L"child::\x6bb5\x843d[position()=last()-1]", L"child::\x6bb5\x843d[position()>1]", L"following-sibling::\x7ae0[position()=1]",
|
||||
L"preceding-sibling::\x7ae0[position()=1]", L"/descendant::\x56f3\x8868[position()=42]", L"/child::\x6587\x66f8/child::\x7ae0[position()=5]/child::\x7bc0[position()=2]",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']", L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a'][position()=5]",
|
||||
L"child::\x6bb5\x843d[position()=5][attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']", L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb='\x306f\x3058\x3081\x306b']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb]", L"child::*[self::\x7ae0 or self::\x4ed8\x9332]", L"child::*[self::\x7ae0 or self::\x4ed8\x9332][position()=last()]",
|
||||
#endif
|
||||
};
|
||||
{
|
||||
#ifdef U_LITERALS
|
||||
L"/descendant-or-self::\u90e8\u5206",
|
||||
L"//\u90e8\u5206",
|
||||
L"substring('\uff11\uff12\uff13\uff14\uff15', 0, 3)",
|
||||
L"//\u30bf\u30a4\u30c8\u30eb | //\u30ea\u30f3\u30af",
|
||||
L"\u8b0e//\u30bf\u30a4\u30c8\u30eb",
|
||||
L"//*[@\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3]",
|
||||
L"\u30da\u30fc\u30b8 = '\u304b\u3089'",
|
||||
L"concat(substring-before(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'),'\u30a2\u30a4\u30b3\u30f3',substring-after(@\u30a4\u30e1\u30fc\u30b8,'\u76ee\u5370'))",
|
||||
L"\u30bd\u30fc\u30b9|\u30c7\u30b9\u30c6\u30a3\u30cd\u30a4\u30b7\u30e7\u30f3",
|
||||
L"\u30da\u30fc\u30b8 != '\u307e\u3067' and \u30da\u30fc\u30b8 != '\u304b\u3089'",
|
||||
L"substring-after(\u30a2\u30a4\u30b3\u30f3/@\u30a4\u30e1\u30fc\u30b8, '/\u5730\u56f3\u30d5\u30a1\u30a4\u30eb/\u76ee\u5370')",
|
||||
L"child::\u6bb5\u843d",
|
||||
L"substring-before(\u6587\u5b57\u5217, \u6587\u5b57)",
|
||||
L"\u30bb\u30b0\u30e1\u30f3\u30c8/@\u6642\u523b",
|
||||
L"attribute::\u540d\u524d",
|
||||
L"descendant::\u6bb5\u843d",
|
||||
L"ancestor::\u90e8\u5206",
|
||||
L"ancestor-or-self::\u90e8\u5206",
|
||||
L"descendant-or-self::\u6bb5\u843d",
|
||||
L"self::\u6bb5\u843d",
|
||||
L"child::\u7ae0/descendant::\u6bb5\u843d",
|
||||
L"child::*/child::\u6bb5\u843d",
|
||||
L"/descendant::\u6bb5\u843d",
|
||||
L"/descendant::\u9806\u5e8f\u30ea\u30b9\u30c8/child::\u9805\u76ee",
|
||||
L"child::\u6bb5\u843d[position()=1]",
|
||||
L"child::\u6bb5\u843d[position()=last()]",
|
||||
L"child::\u6bb5\u843d[position()=last()-1]",
|
||||
L"child::\u6bb5\u843d[position()>1]",
|
||||
L"following-sibling::\u7ae0[position()=1]",
|
||||
L"preceding-sibling::\u7ae0[position()=1]",
|
||||
L"/descendant::\u56f3\u8868[position()=42]",
|
||||
L"/child::\u6587\u66f8/child::\u7ae0[position()=5]/child::\u7bc0[position()=2]",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']",
|
||||
L"child::\u6bb5\u843d[attribute::\u30bf\u30a4\u30d7='\u8b66\u544a'][position()=5]",
|
||||
L"child::\u6bb5\u843d[position()=5][attribute::\u30bf\u30a4\u30d7='\u8b66\u544a']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb='\u306f\u3058\u3081\u306b']",
|
||||
L"child::\u7ae0[child::\u30bf\u30a4\u30c8\u30eb]",
|
||||
L"child::*[self::\u7ae0 or self::\u4ed8\u9332]",
|
||||
L"child::*[self::\u7ae0 or self::\u4ed8\u9332][position()=last()]",
|
||||
#else
|
||||
L"/descendant-or-self::\x90e8\x5206",
|
||||
L"//\x90e8\x5206",
|
||||
L"substring('\xff11\xff12\xff13\xff14\xff15', 0, 3)",
|
||||
L"//\x30bf\x30a4\x30c8\x30eb | //\x30ea\x30f3\x30af",
|
||||
L"\x8b0e//\x30bf\x30a4\x30c8\x30eb",
|
||||
L"//*[@\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3]",
|
||||
L"\x30da\x30fc\x30b8 = '\x304b\x3089'",
|
||||
L"concat(substring-before(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'),'\x30a2\x30a4\x30b3\x30f3',substring-after(@\x30a4\x30e1\x30fc\x30b8,'\x76ee\x5370'))",
|
||||
L"\x30bd\x30fc\x30b9|\x30c7\x30b9\x30c6\x30a3\x30cd\x30a4\x30b7\x30e7\x30f3",
|
||||
L"\x30da\x30fc\x30b8 != '\x307e\x3067' and \x30da\x30fc\x30b8 != '\x304b\x3089'",
|
||||
L"substring-after(\x30a2\x30a4\x30b3\x30f3/@\x30a4\x30e1\x30fc\x30b8, '/\x5730\x56f3\x30d5\x30a1\x30a4\x30eb/\x76ee\x5370')",
|
||||
L"child::\x6bb5\x843d",
|
||||
L"substring-before(\x6587\x5b57\x5217, \x6587\x5b57)",
|
||||
L"\x30bb\x30b0\x30e1\x30f3\x30c8/@\x6642\x523b",
|
||||
L"attribute::\x540d\x524d",
|
||||
L"descendant::\x6bb5\x843d",
|
||||
L"ancestor::\x90e8\x5206",
|
||||
L"ancestor-or-self::\x90e8\x5206",
|
||||
L"descendant-or-self::\x6bb5\x843d",
|
||||
L"self::\x6bb5\x843d",
|
||||
L"child::\x7ae0/descendant::\x6bb5\x843d",
|
||||
L"child::*/child::\x6bb5\x843d",
|
||||
L"/descendant::\x6bb5\x843d",
|
||||
L"/descendant::\x9806\x5e8f\x30ea\x30b9\x30c8/child::\x9805\x76ee",
|
||||
L"child::\x6bb5\x843d[position()=1]",
|
||||
L"child::\x6bb5\x843d[position()=last()]",
|
||||
L"child::\x6bb5\x843d[position()=last()-1]",
|
||||
L"child::\x6bb5\x843d[position()>1]",
|
||||
L"following-sibling::\x7ae0[position()=1]",
|
||||
L"preceding-sibling::\x7ae0[position()=1]",
|
||||
L"/descendant::\x56f3\x8868[position()=42]",
|
||||
L"/child::\x6587\x66f8/child::\x7ae0[position()=5]/child::\x7bc0[position()=2]",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']",
|
||||
L"child::\x6bb5\x843d[attribute::\x30bf\x30a4\x30d7='\x8b66\x544a'][position()=5]",
|
||||
L"child::\x6bb5\x843d[position()=5][attribute::\x30bf\x30a4\x30d7='\x8b66\x544a']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb='\x306f\x3058\x3081\x306b']",
|
||||
L"child::\x7ae0[child::\x30bf\x30a4\x30c8\x30eb]",
|
||||
L"child::*[self::\x7ae0 or self::\x4ed8\x9332]",
|
||||
L"child::*[self::\x7ae0 or self::\x4ed8\x9332][position()=last()]",
|
||||
#endif
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
#if defined(PUGIXML_WCHAR_MODE)
|
||||
#if defined(PUGIXML_WCHAR_MODE)
|
||||
xpath_query q(paths[i]);
|
||||
#elif !defined(PUGIXML_NO_STL)
|
||||
#elif !defined(PUGIXML_NO_STL)
|
||||
std::basic_string<char> path_utf8 = as_utf8(paths[i]);
|
||||
xpath_query q(path_utf8.c_str());
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(xpath_parse_invalid)
|
||||
{
|
||||
const char_t* paths[] =
|
||||
{
|
||||
// From Jaxen tests
|
||||
STR("//:p"), STR("/foo/bar/"), STR("12 + (count(//author)+count(//author/attribute::*)) / 2"), STR("id()/2"), STR("+"),
|
||||
STR("///triple slash"), STR("/numbers numbers"), STR("/a/b[c > d]efg"), STR("/inv/child::"), STR("/invoice/@test[abcd"),
|
||||
STR("/invoice/@test[abcd > x"), STR("string-length('a"), STR("/descendant::()"), STR("(1 + 1"), STR("!false()"),
|
||||
STR("$author"), STR("10 + $foo"), STR("$foo:bar"), STR("$varname[@a='1']"), STR("foo/$variable/foo"),
|
||||
STR(".[1]"), STR("chyld::foo"), STR("foo/tacos()"), STR("foo/tacos()"), STR("/foo/bar[baz"), STR("//"), STR("*:foo"),
|
||||
STR("/cracker/cheese[(mold > 1) and (sense/taste"),
|
||||
const char_t* paths[] =
|
||||
{
|
||||
// From Jaxen tests
|
||||
STR("//:p"), STR("/foo/bar/"), STR("12 + (count(//author)+count(//author/attribute::*)) / 2"), STR("id()/2"), STR("+"),
|
||||
STR("///triple slash"), STR("/numbers numbers"), STR("/a/b[c > d]efg"), STR("/inv/child::"), STR("/invoice/@test[abcd"),
|
||||
STR("/invoice/@test[abcd > x"), STR("string-length('a"), STR("/descendant::()"), STR("(1 + 1"), STR("!false()"),
|
||||
STR("$author"), STR("10 + $foo"), STR("$foo:bar"), STR("$varname[@a='1']"), STR("foo/$variable/foo"),
|
||||
STR(".[1]"), STR("chyld::foo"), STR("foo/tacos()"), STR("foo/tacos()"), STR("/foo/bar[baz"), STR("//"), STR("*:foo"),
|
||||
STR("/cracker/cheese[(mold > 1) and (sense/taste"),
|
||||
|
||||
// From xpath-as3 tests
|
||||
STR("a b"), STR("//self::node())"), STR("/x/y[contains(self::node())"), STR("/x/y[contains(self::node()]"), STR("///"), STR("text::a"),
|
||||
// From xpath-as3 tests
|
||||
STR("a b"), STR("//self::node())"), STR("/x/y[contains(self::node())"), STR("/x/y[contains(self::node()]"), STR("///"), STR("text::a"),
|
||||
|
||||
// From haXe-xpath tests
|
||||
STR("|/gjs"), STR("+3"), STR("/html/body/p != ---'div'/a"), STR(""), STR("@"), STR("#akf"), STR(",")
|
||||
// From haXe-xpath tests
|
||||
STR("|/gjs"), STR("+3"), STR("/html/body/p != ---'div'/a"), STR(""), STR("@"), STR("#akf"), STR(",")
|
||||
|
||||
// Miscellaneous
|
||||
STR("..."), STR("...."), STR("**"), STR("****"), STR("******"), STR("..***..***.***.***..***..***..*"), STR("/[1]")
|
||||
};
|
||||
// Miscellaneous
|
||||
STR("..."),
|
||||
STR("...."), STR("**"), STR("****"), STR("******"), STR("..***..***.***.***..***..***..*"), STR("/[1]")};
|
||||
|
||||
for (size_t i = 0; i < sizeof(paths) / sizeof(paths[0]); ++i)
|
||||
{
|
||||
|
@ -376,35 +426,11 @@ TEST(xpath_parse_oom_propagation)
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -27,9 +27,9 @@ TEST_XML(xpath_paths_axes_descendant, "<node attr='value'><child attr='value'><s
|
|||
|
||||
CHECK_XPATH_NODESET(c, STR("descendant:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("descendant:: node()")) % 4 % 6 % 7 % 8 % 9; // child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("descendant:: node()")) % 4 % 6 % 7 % 8 % 9; // child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant:: node()")) % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant:: node()")) % 8; // subchild
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant:: node()")) % 8; // subchild
|
||||
CHECK_XPATH_NODESET(n, STR("last/descendant:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("@attr/descendant::node()"));
|
||||
|
@ -45,9 +45,9 @@ TEST_XML(xpath_paths_axes_parent, "<node attr='value'><child attr='value'><subch
|
|||
CHECK_XPATH_NODESET(c, STR("parent:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("parent:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/parent:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("@attr/parent:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("parent:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/parent:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("@attr/parent:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("parent:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, STR("parent:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(na, STR("parent:: node()")) % 2; // node
|
||||
|
@ -62,9 +62,9 @@ TEST_XML(xpath_paths_axes_ancestor, "<node attr='value'><child attr='value'><sub
|
|||
CHECK_XPATH_NODESET(c, STR("ancestor:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("ancestor:: node()")) % 2 % 1; // node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(doc, STR("ancestor:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(na, STR("ancestor:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
|
@ -82,7 +82,7 @@ TEST_XML(xpath_paths_axes_following_sibling, "<node attr1='value' attr2='value'>
|
|||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("following-sibling:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("@attr1/following-sibling:: node()")); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(na, STR("following-sibling:: node()")); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(na, STR("following-sibling:: node()")); // attributes are not siblings
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_preceding_sibling, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -97,7 +97,7 @@ TEST_XML(xpath_paths_axes_preceding_sibling, "<node attr1='value' attr2='value'>
|
|||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("preceding-sibling:: node()")) % 8 % 5; // another, child
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("@attr2/following-sibling:: node()")); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(na, STR("following-sibling:: node()")); // attributes are not siblings
|
||||
CHECK_XPATH_NODESET(na, STR("following-sibling:: node()")); // attributes are not siblings
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_following, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild/></another><almost/><last/></node>")
|
||||
|
@ -108,14 +108,14 @@ TEST_XML(xpath_paths_axes_following, "<node attr1='value' attr2='value'><child a
|
|||
|
||||
CHECK_XPATH_NODESET(c, STR("following:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("following:: node()")); // no descendants
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("following:: node()")) % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n, STR("following:: node()")); // no descendants
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("following:: node()")) % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")).child(STR("subchild")), STR("following:: node()")) % 8 % 9 % 10 % 11; // another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("following:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("@attr1/following::node()")) % 5 % 7 % 8 % 9 % 10 % 11; // child, subchild, another, subchild, almost, last - because @/following
|
||||
CHECK_XPATH_NODESET(n, STR("@attr1/following::node()")) % 5 % 7 % 8 % 9 % 10 % 11; // child, subchild, another, subchild, almost, last - because @/following
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/following::node()")) % 7 % 8 % 9 % 10 % 11; // subchild, another, subchild, almost, last
|
||||
CHECK_XPATH_NODESET(na, STR("following::node()")) % 5 % 7 % 8 % 9 % 10 % 11; // child, subchild, another, subchild, almost, last - because @/following
|
||||
CHECK_XPATH_NODESET(na, STR("following::node()")) % 5 % 7 % 8 % 9 % 10 % 11; // child, subchild, another, subchild, almost, last - because @/following
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_preceding, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another><subchild id='1'/></another><almost/><last/></node>")
|
||||
|
@ -126,14 +126,14 @@ TEST_XML(xpath_paths_axes_preceding, "<node attr1='value' attr2='value'><child a
|
|||
|
||||
CHECK_XPATH_NODESET(c, STR("preceding:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("preceding:: node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("preceding:: node()")) % 11 % 9 % 8 % 7 % 5; // almost, subchild, another, subchild, child
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("preceding:: node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("preceding:: node()")) % 11 % 9 % 8 % 7 % 5; // almost, subchild, another, subchild, child
|
||||
CHECK_XPATH_NODESET(n.child(STR("another")).child(STR("subchild")), STR("preceding:: node()")) % 7 % 5; // subchild, child
|
||||
CHECK_XPATH_NODESET(n, STR("preceding:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/preceding::node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/preceding::node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(n, STR("//subchild[@id]/@id/preceding::node()")) % 7 % 5; // subchild, child
|
||||
CHECK_XPATH_NODESET(na, STR("preceding::node()")); // no ancestors
|
||||
CHECK_XPATH_NODESET(na, STR("preceding::node()")); // no ancestors
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_attribute, "<node attr1='value' attr2='value'><child attr='value'><subchild/></child><another xmlns:foo='bar'><subchild/></another><last/></node>")
|
||||
|
@ -146,9 +146,9 @@ TEST_XML(xpath_paths_axes_attribute, "<node attr1='value' attr2='value'><child a
|
|||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("attribute:: node()")) % 6; // child/@attr
|
||||
CHECK_XPATH_NODESET(n.child(STR("last")), STR("attribute:: node()"));
|
||||
CHECK_XPATH_NODESET(n, STR("attribute:: node()")) % 3 % 4; // node/@attr1 node/@attr2
|
||||
CHECK_XPATH_NODESET(n, STR("attribute:: node()")) % 3 % 4; // node/@attr1 node/@attr2
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant-or-self:: node()/attribute:: node()")) % 3 % 4 % 6; // all attributes
|
||||
CHECK_XPATH_NODESET(n.child(STR("another")), STR("attribute:: node()")); // namespace nodes are not attributes
|
||||
CHECK_XPATH_NODESET(n.child(STR("another")), STR("attribute:: node()")); // namespace nodes are not attributes
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("@attr1/attribute::node()"));
|
||||
CHECK_XPATH_NODESET(na, STR("attribute::node()"));
|
||||
|
@ -174,11 +174,11 @@ TEST_XML(xpath_paths_axes_self, "<node attr='value'><child attr='value'><subchil
|
|||
CHECK_XPATH_NODESET(c, STR("self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("self:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("self:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("child/self:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/self:: node()")) % 5; // @attr
|
||||
CHECK_XPATH_NODESET(doc, STR("self:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(na, STR("self:: node()")) % 3; // @attr
|
||||
CHECK_XPATH_NODESET(n, STR("self:: node()")) % 2; // node
|
||||
CHECK_XPATH_NODESET(n, STR("child/self:: node()")) % 4; // child
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/self:: node()")) % 5; // @attr
|
||||
CHECK_XPATH_NODESET(doc, STR("self:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(na, STR("self:: node()")) % 3; // @attr
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_descendant_or_self, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -189,13 +189,13 @@ TEST_XML(xpath_paths_axes_descendant_or_self, "<node attr='value'><child attr='v
|
|||
|
||||
CHECK_XPATH_NODESET(c, STR("descendant-or-self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("descendant-or-self:: node()")) % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("descendant-or-self:: node()")) % 2 % 4 % 6 % 7 % 8 % 9; // node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(doc, STR("descendant-or-self:: node()")) % 1 % 2 % 4 % 6 % 7 % 8 % 9; // root, node, child, subchild, another, subchild, last
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant-or-self:: node()")) % 7 % 8; // another, subchild
|
||||
CHECK_XPATH_NODESET(n, STR("last/descendant-or-self:: node()")) % 9; // last
|
||||
CHECK_XPATH_NODESET(n, STR("another/descendant-or-self:: node()")) % 7 % 8; // another, subchild
|
||||
CHECK_XPATH_NODESET(n, STR("last/descendant-or-self:: node()")) % 9; // last
|
||||
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/descendant-or-self::node()")) % 5; // @attr
|
||||
CHECK_XPATH_NODESET(na, STR("descendant-or-self::node()")) % 5; // @attr
|
||||
CHECK_XPATH_NODESET(na, STR("descendant-or-self::node()")) % 5; // @attr
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_ancestor_or_self, "<node attr='value'><child attr='value'><subchild/></child><another><subchild/></another><last/></node>")
|
||||
|
@ -207,13 +207,13 @@ TEST_XML(xpath_paths_axes_ancestor_or_self, "<node attr='value'><child attr='val
|
|||
CHECK_XPATH_NODESET(c, STR("ancestor-or-self:: node()"));
|
||||
|
||||
CHECK_XPATH_NODESET(n.child(STR("child")), STR("ancestor-or-self:: node()")) % 4 % 2 % 1; // child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor-or-self:: node()")) % 6 % 4 % 2 % 1; // subchild, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor-or-self:: node()")) % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor-or-self:: node()")) % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(doc, STR("ancestor-or-self:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor-or-self:: node()")) % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(n, STR("last/ancestor-or-self::node()")) % 9 % 2 % 1; // root, node, last
|
||||
CHECK_XPATH_NODESET(na, STR("ancestor-or-self:: node()")) % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/subchild/ancestor-or-self:: node()")) % 6 % 4 % 2 % 1; // subchild, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("child/@attr/ancestor-or-self:: node()")) % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor-or-self:: node()")) % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(doc, STR("ancestor-or-self:: node()")) % 1; // root
|
||||
CHECK_XPATH_NODESET(n, STR("ancestor-or-self:: node()")) % 2 % 1; // root, node
|
||||
CHECK_XPATH_NODESET(n, STR("last/ancestor-or-self::node()")) % 9 % 2 % 1; // root, node, last
|
||||
CHECK_XPATH_NODESET(na, STR("ancestor-or-self:: node()")) % 5 % 4 % 2 % 1; // @attr, child, node, root
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_axes_abbrev, "<node attr='value'><foo/></node>")
|
||||
|
@ -561,7 +561,7 @@ TEST_XML(xpath_paths_descendant_double_slash_w3c, "<node><para><para/><para/><pa
|
|||
|
||||
TEST_XML(xpath_paths_needs_sorting, "<node><child/><child/><child><subchild/><subchild/></child></node>")
|
||||
{
|
||||
CHECK_XPATH_NODESET(doc, STR("(node/child/subchild)[2]")) % 7;
|
||||
CHECK_XPATH_NODESET(doc, STR("(node/child/subchild)[2]")) % 7;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_descendant_filters, "<node><para><para/><para/><para><para/></para></para><para/></node>")
|
||||
|
@ -657,53 +657,53 @@ TEST_XML(xpath_paths_optimize_compare_attribute, "<node id='1' /><node id='2' />
|
|||
|
||||
TEST_XML(xpath_paths_optimize_step_once, "<node><para1><para2/><para3/><para4><para5 attr5=''/></para4></para1><para6/></node>")
|
||||
{
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para2/following::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/following::*"), false);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para2/following::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/following::*"), false);
|
||||
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para2/following::*)"), STR("para3"));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para6/following::*)"), STR(""));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para2/following::*)"), STR("para3"));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para6/following::*)"), STR(""));
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para1/preceding::*"), false);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para1/preceding::*"), false);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::*"), true);
|
||||
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para1/preceding::*)"), STR(""));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para6/preceding::*)"), STR("para1"));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para1/preceding::*)"), STR(""));
|
||||
CHECK_XPATH_STRING(doc, STR("name(node//para6/preceding::*)"), STR("para1"));
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::para4"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::para4"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor-or-self::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor-or-self::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor::*"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/following::para6"), true);
|
||||
CHECK_XPATH_STRING(doc, STR("name(//@attr5/following::para6)"), STR("para6"));
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/following::para6"), true);
|
||||
CHECK_XPATH_STRING(doc, STR("name(//@attr5/following::para6)"), STR("para6"));
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//para5/ancestor-or-self::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//para5/ancestor::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//para5/ancestor-or-self::*"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//para5/ancestor::*"), true);
|
||||
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor-or-self::node()"), true);
|
||||
CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor-or-self::node()"), true);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_paths_null_nodeset_entries, "<node attr='value'/>")
|
||||
{
|
||||
xpath_node nodes[] =
|
||||
{
|
||||
xpath_node(doc.first_child()),
|
||||
xpath_node(xml_node()),
|
||||
xpath_node(doc.first_child().first_attribute(), doc.first_child()),
|
||||
xpath_node(xml_attribute(), doc.first_child()),
|
||||
xpath_node(xml_attribute(), xml_node()),
|
||||
};
|
||||
xpath_node nodes[] =
|
||||
{
|
||||
xpath_node(doc.first_child()),
|
||||
xpath_node(xml_node()),
|
||||
xpath_node(doc.first_child().first_attribute(), doc.first_child()),
|
||||
xpath_node(xml_attribute(), doc.first_child()),
|
||||
xpath_node(xml_attribute(), xml_node()),
|
||||
};
|
||||
|
||||
xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
|
||||
xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]));
|
||||
|
||||
xpath_variable_set vars;
|
||||
vars.set(STR("x"), ns);
|
||||
xpath_variable_set vars;
|
||||
vars.set(STR("x"), ns);
|
||||
|
||||
xpath_node_set rs = xpath_query(STR("$x/."), &vars).evaluate_node_set(xml_node());
|
||||
xpath_node_set rs = xpath_query(STR("$x/."), &vars).evaluate_node_set(xml_node());
|
||||
|
||||
CHECK(rs.size() == 2);
|
||||
CHECK(rs[0] == nodes[0]);
|
||||
CHECK(rs[1] == nodes[2]);
|
||||
CHECK(rs.size() == 2);
|
||||
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>")
|
||||
|
|
|
@ -404,11 +404,11 @@ TEST(xpath_variables_name_case)
|
|||
TEST(xpath_variables_name_unicode)
|
||||
{
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
#ifdef U_LITERALS
|
||||
const char_t* name = L"\u0400\u203D";
|
||||
#else
|
||||
const char_t* name = L"\x0400\x203D";
|
||||
#endif
|
||||
#ifdef U_LITERALS
|
||||
const char_t* name = L"\u0400\u203D";
|
||||
#else
|
||||
const char_t* name = L"\x0400\x203D";
|
||||
#endif
|
||||
#else
|
||||
const char_t* name = "\xd0\x80\xe2\x80\xbd";
|
||||
#endif
|
||||
|
@ -454,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 = xpath_variable_set(set3);
|
||||
set3 = set3;
|
||||
|
||||
CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
|
||||
|
||||
|
@ -642,32 +642,4 @@ TEST_XML(xpath_variables_evaluate_node_set_out_of_memory, "<node />")
|
|||
|
||||
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
|
||||
|
|
|
@ -322,16 +322,16 @@ TEST(xpath_xalan_math_5)
|
|||
CHECK_XPATH_NUMBER(c, STR("10+5+25+20+15+50+35+40"), 200);
|
||||
CHECK_XPATH_NUMBER(c, STR("100-9-7-4-17-18-5"), 40);
|
||||
CHECK_XPATH_NUMBER(c, STR("3*2+5*4-4*2-1"), 17);
|
||||
CHECK_XPATH_NUMBER(c, STR("6*5-8*2+5*2"), 24);
|
||||
CHECK_XPATH_NUMBER(c, STR("10*5-4*2+6*1 -3*3"), 39);
|
||||
CHECK_XPATH_NUMBER(c, STR("6*5-8*2+5*2"), 24);
|
||||
CHECK_XPATH_NUMBER(c, STR("10*5-4*2+6*1 -3*3"), 39);
|
||||
|
||||
CHECK_XPATH_NUMBER(c, STR("(24 div 3 +2) div (40 div 8 -3)"), 5);
|
||||
CHECK_XPATH_NUMBER(c, STR("80 div 2 + 12 div 2 - 4 div 2"), 44);
|
||||
CHECK_XPATH_NUMBER(c, STR("70 div 10 - 18 div 6 + 10 div 2"), 9);
|
||||
CHECK_XPATH_NUMBER(c, STR("(24 div 3 +2) div (40 div 8 -3)"), 5);
|
||||
CHECK_XPATH_NUMBER(c, STR("80 div 2 + 12 div 2 - 4 div 2"), 44);
|
||||
CHECK_XPATH_NUMBER(c, STR("70 div 10 - 18 div 6 + 10 div 2"), 9);
|
||||
|
||||
CHECK_XPATH_NUMBER(c, STR("48 mod 17 - 2 mod 9 + 13 mod 5"), 15);
|
||||
CHECK_XPATH_NUMBER(c, STR("56 mod round(5*2+1.444) - 6 mod 4 + 7 mod 4"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("(77 mod 10 + 5 mod 8) mod 10"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("48 mod 17 - 2 mod 9 + 13 mod 5"), 15);
|
||||
CHECK_XPATH_NUMBER(c, STR("56 mod round(5*2+1.444) - 6 mod 4 + 7 mod 4"), 2);
|
||||
CHECK_XPATH_NUMBER(c, STR("(77 mod 10 + 5 mod 8) mod 10"), 2);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_xalan_math_6, "<doc><n1>3</n1><n2>7</n2><n3>x</n3></doc>")
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ TEST_XML(xpath_xalan_axes_9, "<doc><foo att1='c'><foo att1='b'><foo att1='a'><ba
|
|||
xml_node baz = doc.select_node(STR("//baz")).node();
|
||||
|
||||
CHECK_XPATH_NODESET(baz, STR("ancestor-or-self::*[@att1][1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*)[@att1][1]/@att1")) % 4;
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*)[@att1][1]/@att1")) % 4;
|
||||
|
||||
CHECK_XPATH_NODESET(baz, STR("ancestor::foo[1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor::foo[1])/@att1")) % 8;
|
||||
|
@ -203,7 +203,7 @@ TEST_XML(xpath_xalan_axes_9, "<doc><foo att1='c'><foo att1='b'><foo att1='a'><ba
|
|||
|
||||
xml_node bar = doc.child(STR("doc")).child(STR("bar"));
|
||||
|
||||
CHECK_XPATH_NODESET(bar, STR("preceding::foo[1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(bar, STR("preceding::foo[1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(bar, STR("(preceding::foo)[1]/@att1")) % 4;
|
||||
}
|
||||
|
||||
|
@ -211,7 +211,7 @@ TEST_XML(xpath_xalan_axes_10, "<doc><foo att1='c'/><foo att1='b'/><foo att1='a'/
|
|||
{
|
||||
xml_node baz = doc.child(STR("doc")).child(STR("baz"));
|
||||
|
||||
CHECK_XPATH_NODESET(baz, STR("preceding-sibling::foo[1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(baz, STR("preceding-sibling::foo[1]/@att1")) % 8;
|
||||
CHECK_XPATH_NODESET(baz, STR("(preceding-sibling::foo)[1]/@att1")) % 4;
|
||||
}
|
||||
|
||||
|
@ -219,10 +219,10 @@ TEST_XML(xpath_xalan_axes_11, "<chapter title='A' x='0'><section title='A1' x='1
|
|||
{
|
||||
xml_node chapter = doc.child(STR("chapter"));
|
||||
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//@*)"), 16);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//@title)"), 12);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//section//@*)"), 14);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//section//@title)"), 11);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//@*)"), 16);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//@title)"), 12);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//section//@*)"), 14);
|
||||
CHECK_XPATH_NUMBER(doc, STR("count(//section//@title)"), 11);
|
||||
|
||||
CHECK_XPATH_NUMBER(chapter, STR("count(.//@*)"), 16);
|
||||
CHECK_XPATH_NUMBER(chapter, STR("count(.//@title)"), 12);
|
||||
|
@ -254,13 +254,13 @@ TEST_XML(xpath_xalan_axes_13, "<doc att1='e'><foo att1='d'><foo att1='c'><foo at
|
|||
CHECK_XPATH_NODESET(d, STR("(descendant-or-self::*/@att1)[last()]")) % 11;
|
||||
|
||||
CHECK_XPATH_NUMBER(baz, STR("count(ancestor-or-self::*/@att1)"), 5);
|
||||
CHECK_XPATH_NODESET(baz, STR("ancestor-or-self::*/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string(ancestor-or-self::*/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*)/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string((ancestor-or-self::*)/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*/@att1)[last()]")) % 11;
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor::*|self::*)/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string((ancestor::*|self::*)/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("ancestor-or-self::*/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string(ancestor-or-self::*/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*)/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string((ancestor-or-self::*)/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*/@att1)[last()]")) % 11;
|
||||
CHECK_XPATH_NODESET(baz, STR("(ancestor::*|self::*)/@att1[last()]")) % 3 % 5 % 7 % 9 % 11;
|
||||
CHECK_XPATH_STRING(baz, STR("string((ancestor::*|self::*)/@att1[last()])"), STR("e"));
|
||||
CHECK_XPATH_NODESET(baz, STR("((ancestor::*|self::*)/@att1)[last()]")) % 11;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,12 +52,12 @@ TEST_XML_FLAGS(xpath_xalan_position_2, "<doc><a test='true'><num>1</num></a><a><
|
|||
CHECK_XPATH_NODESET(c, STR("processing-instruction()[2]")) % 34;
|
||||
CHECK_XPATH_NODESET(c, STR("processing-instruction('pi')[2]")) % 34;
|
||||
CHECK_XPATH_NODESET(c, STR("comment()[2]")) % 36;
|
||||
CHECK_XPATH_NODESET(c, STR("a/*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/child::*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/descendant::*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 31;
|
||||
CHECK_XPATH_NODESET(c, STR("a/child::node()[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/descendant::text()[last()]")) % 6 % 9 % 12 % 16 % 19 % 22 % 26 % 32;
|
||||
CHECK_XPATH_NODESET(c, STR("child::comment()[last()]")) % 36;
|
||||
CHECK_XPATH_NODESET(c, STR("a/*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/child::*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/descendant::*[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 31;
|
||||
CHECK_XPATH_NODESET(c, STR("a/child::node()[last()]")) % 5 % 8 % 11 % 15 % 18 % 21 % 25 % 29;
|
||||
CHECK_XPATH_NODESET(c, STR("a/descendant::text()[last()]")) % 6 % 9 % 12 % 16 % 19 % 22 % 26 % 32;
|
||||
CHECK_XPATH_NODESET(c, STR("child::comment()[last()]")) % 36;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_xalan_position_3, "<article class='whitepaper' status='Note'><articleinfo><title>AAA</title><section id='info'><title>BBB</title><para>About this article</para><section revisionflag='added'><title>CCC</title><para>This is the section titled 'ZZZ'.</para><ednote who='KKK'><title>DDD</title><para>Don't worry.</para><section revisionflag='added'><title>EEE</title><para>This is the deep subsection.</para></section></ednote></section></section></articleinfo></article>")
|
||||
|
@ -111,7 +111,6 @@ TEST_XML(xpath_xalan_match_1, "<root><x spot='a' num='1'/><x spot='b' num='2'/><
|
|||
CHECK_XPATH_NODESET(c, STR("x[(((((2*10)-4)+9) div 5) mod 3)]")) % 6;
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(xpath_xalan_match_2, "<doc><l1><v2>doc-l1-v2</v2><x2>doc-l1-x2</x2><l2><v3>doc-l1-l2-v3</v3><w3>doc-l1-l2-w3</w3><x3>doc-l1-l2-x3</x3><y3>doc-l1-l2-y3</y3><l3><v4>doc-l1-l2-l3-v4</v4><x4>doc-l1-l2-l3-x4</x4></l3></l2></l1></doc>")
|
||||
{
|
||||
CHECK_XPATH_STRING(doc, STR("doc/l1/v2"), STR("doc-l1-v2"));
|
||||
|
|
|
@ -111,7 +111,7 @@ TEST_XML(xpath_xalan_select_11, "<doc><sub1 pos='1'><child1>descendant number 1<
|
|||
|
||||
TEST_XML(xpath_xalan_select_12, "<doc><sub pos='1'><child>child number 1</child><sub-sub pos='1sub'><child>grandchild number 1</child></sub-sub></sub><sub0 pos='2-no'><child>child number 2</child><sub pos='2.5'><child>grandchild number 2</child></sub></sub0><sub pos='3'><child>child number 3</child><subno pos='3.5-no'><child>grandchild number 3</child></subno></sub><sub0 pos='4-no'><child>child number 4</child><sub-sub pos='4sub'><child>grandchild number 4</child></sub-sub></sub0></doc>")
|
||||
{
|
||||
CHECK_XPATH_NODESET(doc, STR("//child/ancestor-or-self::sub | //child/ancestor-or-self::sub-sub")) % 3 % 7 % 15 % 19 % 31;
|
||||
CHECK_XPATH_NODESET(doc, STR("//child/ancestor-or-self::sub | //child/ancestor-or-self::sub-sub")) % 3 % 7 % 15 % 19 % 31;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_xalan_select_13, "<doc><book><author><name real='no'>Carmelo Montanez</name><chapters>Nine</chapters><bibliography></bibliography></author></book><book><author><name real='na'>David Marston</name><chapters>Seven</chapters><bibliography></bibliography></author></book><book><author><name real='yes'>Mary Brady</name><chapters>Ten</chapters><bibliography><author><name>Lynne Rosenthal</name><chapters>Five</chapters></author></bibliography></author></book></doc>")
|
||||
|
@ -154,17 +154,17 @@ TEST_XML(xpath_xalan_select_17, "<directions><north><dup1/><dup2/><south/><east/
|
|||
{
|
||||
xml_node c = doc.child(STR("directions"));
|
||||
|
||||
CHECK_XPATH_NODESET(c, STR("north/* | north/dup1 | north/dup2")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("north/dup2 | north/dup1 | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("//north/dup2 | south/preceding-sibling::*[4]/* | north/dup1 | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("north/dup2 | south/preceding-sibling::*[4]/* | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("north/* | north/dup1 | north/dup2")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("north/dup2 | north/dup1 | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("//north/dup2 | south/preceding-sibling::*[4]/* | north/dup1 | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
CHECK_XPATH_NODESET(c, STR("north/dup2 | south/preceding-sibling::*[4]/* | north/*")) % 4 % 5 % 6 % 7 % 8;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_xalan_select_18, "<para><font color='red'>Hello</font><font color='green'>There</font><font color='blue'>World</font></para>")
|
||||
{
|
||||
CHECK_XPATH_NODESET(doc, STR("/para/font[@color='green']")) % 6;
|
||||
CHECK_XPATH_NODESET(doc.child(STR("para")), STR("/para/font[@color='green']")) % 6;
|
||||
CHECK_XPATH_NODESET(doc.child(STR("para")).last_child(), STR("/para/font[@color='green']")) % 6;
|
||||
CHECK_XPATH_NODESET(doc, STR("/para/font[@color='green']")) % 6;
|
||||
CHECK_XPATH_NODESET(doc.child(STR("para")), STR("/para/font[@color='green']")) % 6;
|
||||
CHECK_XPATH_NODESET(doc.child(STR("para")).last_child(), STR("/para/font[@color='green']")) % 6;
|
||||
}
|
||||
|
||||
TEST_XML_FLAGS(xpath_xalan_select_19, "<doc>1<a>in-a</a>2<!-- upper comment --><b>3<bb>4<bbb>5</bbb>6</bb>7</b><!-- lower comment -->8<c>in-c</c>9<?pi?></doc>", parse_default | parse_comments | parse_pi)
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
static bool test_narrow(const std::string& result, const char* expected, size_t length)
|
||||
{
|
||||
// check result
|
||||
if (result != std::string(expected, expected + length)) return false;
|
||||
if (result != std::string(expected, expected + length))
|
||||
return false;
|
||||
|
||||
// check comparison operator (incorrect implementation can theoretically early-out on zero terminators...)
|
||||
if (length > 0 && result == std::string(expected, expected + length - 1) + "?") return false;
|
||||
if (length > 0 && result == std::string(expected, expected + length - 1) + "?")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -27,7 +29,7 @@ std::basic_string<wchar_t> xml_writer_string::as_wide() const
|
|||
{
|
||||
CHECK(contents.size() % sizeof(wchar_t) == 0);
|
||||
|
||||
// round-trip pointer through void* to avoid pointer alignment warnings; contents data should be heap allocated => safe to cast
|
||||
// round-trip pointer through void* to avoid pointer alignment warnings; contents data should be heap allocated => safe to cast
|
||||
return std::basic_string<wchar_t>(static_cast<const wchar_t*>(static_cast<const void*>(contents.data())), contents.size() / sizeof(wchar_t));
|
||||
}
|
||||
|
||||
|
@ -37,7 +39,7 @@ std::basic_string<pugi::char_t> xml_writer_string::as_string() const
|
|||
CHECK(contents.size() % sizeof(pugi::char_t) == 0);
|
||||
#endif
|
||||
|
||||
// round-trip pointer through void* to avoid pointer alignment warnings; contents data should be heap allocated => safe to cast
|
||||
// round-trip pointer through void* to avoid pointer alignment warnings; contents data should be heap allocated => safe to cast
|
||||
return std::basic_string<pugi::char_t>(static_cast<const pugi::char_t*>(static_cast<const void*>(contents.data())), contents.size() / sizeof(pugi::char_t));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
struct xml_writer_string: public pugi::xml_writer
|
||||
struct xml_writer_string : public pugi::xml_writer
|
||||
{
|
||||
std::string contents;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue