diff --git a/.github/workflows/autotools-clang.yml b/.github/workflows/autotools-clang.yml new file mode 100644 index 00000000..4e9b184e --- /dev/null +++ b/.github/workflows/autotools-clang.yml @@ -0,0 +1,25 @@ +name: "Autotools: clang" + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Build + run: | + sudo apt update + sudo apt install libxml2-dev mm-common clang docbook-xsl + export CXX=clang++ + ./autogen.sh --enable-warnings=fatal + make + - name: Test + run: make check + - name: Distcheck + run: | + # distcheck runs configure again so we need to specify CXX again. + export CXX=clang++ + make distcheck diff --git a/.github/workflows/autotools-gcc.yml b/.github/workflows/autotools-gcc.yml new file mode 100644 index 00000000..532e4b77 --- /dev/null +++ b/.github/workflows/autotools-gcc.yml @@ -0,0 +1,25 @@ +name: "Autotools: gcc" + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Build + run: | + sudo apt update + sudo apt install libxml2-dev mm-common g++ docbook-xsl + export CXX=g++ + ./autogen.sh --enable-warnings=fatal + make + - name: Test + run: make check + - name: Distcheck + run: | + # distcheck runs configure again so we need to specify CXX again. + export CXX=g++ + make distcheck diff --git a/.github/workflows/meson-clang.yml b/.github/workflows/meson-clang.yml new file mode 100644 index 00000000..dd8d4a11 --- /dev/null +++ b/.github/workflows/meson-clang.yml @@ -0,0 +1,39 @@ +# 2024-07-15: ubuntu-latest = ubuntu-22.04 +# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories +name: "Meson: clang" + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Build + run: | + # Prevent blocking apt install on a question during configuring of tzdata. + export DEBIAN_FRONTEND=noninteractive + sudo apt update + sudo apt install libxml2-dev libxml2-utils docbook5-xml docbook-xsl mm-common clang ninja-build python3-setuptools python3-pip --yes + # Ubuntu 22.04 contains meson 0.61.2, but libxml++ requires meson >= 0.62.0. + # Install it with pip instead of apt. + sudo pip install "meson>=0.62.0" + export CC=clang + export CXX=clang++ + meson setup -Dwarnings=fatal -Dwarning_level=3 -Dwerror=true _build + cd _build + meson compile + - name: Test + run: | + cd _build + meson test + - name: Dist + run: | + sudo apt install git --yes + # dist runs setup again so we need to specify CC and CXX again. + export CC=clang + export CXX=clang++ + cd _build + meson dist diff --git a/.github/workflows/meson-gcc.yml b/.github/workflows/meson-gcc.yml new file mode 100644 index 00000000..aaa1eff6 --- /dev/null +++ b/.github/workflows/meson-gcc.yml @@ -0,0 +1,39 @@ +# 2024-07-15: ubuntu-latest = ubuntu-22.04 +# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories +name: "Meson: gcc" + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Build + run: | + # Prevent blocking apt install on a question during configuring of tzdata. + export DEBIAN_FRONTEND=noninteractive + sudo apt update + sudo apt install libxml2-dev libxml2-utils docbook5-xml docbook-xsl mm-common g++ ninja-build python3-setuptools python3-pip --yes + # Ubuntu 22.04 contains meson 0.61.2, but libxml++ requires meson >= 0.62.0. + # Install it with pip instead of apt. + sudo pip install "meson>=0.62.0" + export CC=gcc + export CXX=g++ + meson setup -Dwarnings=fatal -Dwarning_level=3 -Dwerror=true _build + cd _build + meson compile + - name: Test + run: | + cd _build + meson test + - name: Dist + run: | + sudo apt install git --yes + # dist runs setup again so we need to specify CC and CXX again. + export CC=gcc + export CXX=g++ + cd _build + meson dist diff --git a/.github/workflows/meson-windows-2022.yml b/.github/workflows/meson-windows-2022.yml new file mode 100644 index 00000000..67bc84ec --- /dev/null +++ b/.github/workflows/meson-windows-2022.yml @@ -0,0 +1,38 @@ +name: "meson: windows 2022" + +on: [push, workflow_dispatch] + +jobs: + build: + + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - run: pip install meson ninja + + - name: Prepare MSVC + uses: bus1/cabuild/action/msdevshell@v1 + with: + architecture: x64 + + - name: Configure + run: meson setup --warnlevel 3 -Dlibxml2:warning_level=0 --werror -Dlibxml2:werror=false -Dlibxml2:python=disabled -Dlibxml2:iconv=disabled -Dmaintainer-mode=false _build + + - name: Compile + run: ninja -C _build + + - name: Test + run: meson test -C _build + + - name: Configure static + run: meson setup --warnlevel 3 -Dlibxml2:warning_level=0 --werror -Dlibxml2:werror=false -Dlibxml2:python=disabled -Dlibxml2:iconv=disabled --default-library static -Dmaintainer-mode=false _build_static + + - name: Compile static + run: ninja -C _build_static + + - name: Test static + run: meson test -C _build_static diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 00000000..c4a885b4 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,80 @@ +# Sample workflow for building and deploying a Jekyll site to GitHub Pages + +# Copied from https://github.com/libxmlplusplus/libxmlplusplus/actions/new +# and changed. Actions -> New workflow -> Pages -> GitHub Pages Jekyll + +name: Publish docs + +# 2024-12-12: ubuntu-latest = ubuntu-22.04 +# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build + run: | + # Prevent blocking apt install on a question during configuring of tzdata. + export DEBIAN_FRONTEND=noninteractive + sudo apt update + sudo apt install libxml2-dev libxml2-utils docbook5-xml docbook-xsl mm-common g++ ninja-build python3-setuptools python3-pip --yes + # Ubuntu 22.04 contains meson 0.61.2, but libxml++ requires meson >= 0.62.0. + # Install it with pip instead of apt. + sudo pip install "meson>=0.62.0" + meson setup -Dbuild-documentation=true -Dbuild-examples=false -Dbuild-tests=false _build + meson compile -C _build + - name: Collect Documentation + # Collect all documentation to be published. + run: | + mkdir _publish _publish/_layouts _publish/manual _publish/reference + # Copy files from the git repository. + cp docs/_config.yml docs/*.md docs/style.css _publish + cp docs/_layouts/*.html _publish/_layouts + # Move generated documentation. + mv _build/docs/manual/html _publish/manual + mv _build/docs/reference/html _publish/reference + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Build with Jekyll + uses: actions/jekyll-build-pages@v1 + with: + source: ./_publish + destination: ./_site + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + # Deployment job + # Publish documentation at https://libxmlplusplus.github.io/libxmlplusplus/ + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 + diff --git a/.gitignore b/.gitignore index 2c27b84f..4ffe2322 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # wildcard patterns *.[ao] *.l[ao] -*~ Makefile Makefile.in .deps/ @@ -21,12 +20,12 @@ stamp-h? /config.status /configure /configure.lineno -/libxml++-2.6.pc +/libxml++-*.pc /libxml++-*.tar.* /libtool # MSVC -/MSVC_Net201?/libxml++/libxml++.rc +/MSVC_NMake/libxml++/libxml++.rc # docs /docs/doc-install.pl @@ -34,13 +33,14 @@ stamp-h? /docs/doxygen.css /docs/doxygen-extra.css /docs/tagfile-to-devhelp2.xsl +/docs/manual/__pycache__/ /docs/manual/html/ /docs/manual/libxml++.xml /docs/reference/Doxyfile /docs/reference/doxygen.log /docs/reference/html/ -/docs/reference/libxml++-2.6.devhelp2 -/docs/reference/libxml++-2.6.tag +/docs/reference/libxml++-*.devhelp2 +/docs/reference/libxml++-*.tag # examples /examples/dom_build/dom_build @@ -65,27 +65,12 @@ stamp-h? /examples/*/make_check.sh.trs /examples/test-suite.log -# macros -/macros/compile -/macros/compile-binding.am -/macros/config.guess -/macros/config.sub -/macros/depcomp -/macros/dist-changelog.am -/macros/doc-reference.am -/macros/generate-binding.am -/macros/install-sh -/macros/libtool.m4 -/macros/ltmain.sh -/macros/ltoptions.m4 -/macros/ltsugar.m4 -/macros/ltversion.m4 -/macros/lt~obsolete.m4 -/macros/missing -/macros/test-driver - # tests /tests/*/test /tests/*/test.log /tests/*/test.trs /tests/test-suite.log + +# untracked/ +untracked/build_scripts/ +untracked/docs/ diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index e3c5a395..00000000 --- a/AUTHORS +++ /dev/null @@ -1,17 +0,0 @@ -Please do not email us directly - use the mailing list. -See http://libxmlplusplus.sourceforge.net - -Maintainer ----------- -Christophe de Vienne - -Contributors ------------- - See the ChangeLog. - -Previous Maintainers: ----------------- - -Ari Johnson - - diff --git a/COPYING b/COPYING index b1e3f5a2..2551a65a 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -484,8 +484,7 @@ convey the exclusion of warranty; and each file should have at least the Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . Also add information on how to contact you by electronic and paper mail. diff --git a/ChangeLog.pre-2-36-0 b/ChangeLog.pre-2-36-0 deleted file mode 100644 index 0b836fe1..00000000 --- a/ChangeLog.pre-2-36-0 +++ /dev/null @@ -1,2839 +0,0 @@ -2.36.0: - -2012-10-25 Kjell Ahlstedt - - Element::set_namespace_declaration(): No error to set the same URI twice. - - * libxml++/nodes/element.[h|cc]: Don't throw an exception from - set_namespace_declaration(), if a namespace prefix is assigned the same URI - twice. Bug #635846, comment 27. - -2012-10-10 Kjell Ahlstedt - - Require libxml-2.0 >= 2.7.3. - - * configure.ac: Require libxml-2.0 >= 2.7.3. - Don't know if it's really necessary, but 2.7.2 from 2008-10-03 is the oldest - release available at ftp://xmlsoft.org/libxml2, and 2.7.2 contains a bug that - makes examples/import_node segfault. - -2012-10-10 Kjell Ahlstedt - - Parser::initialize_context(): Call xmlCtxtUseOptions(). - - * libxml++/parsers/parser.cc: initialize_context(): Call xmlCtxtUseOptions() - instead of setting context_->validate and replaceEntities. - xmlCtxtUseOptions() does that and more. - -2.35.4: - -2012-08-28 Kjell Ahlstedt - - Add XInclude processing. - - * Makefile.am: Add XIncludeStart and XIncludeEnd nodes. - * examples/Makefile.am: Add dom_xinclude example. - * examples/README: Add dom_xinclude example and other missing examples. - * examples/dom_xinclude/example.xml: - * examples/dom_xinclude/include1.txt: - * examples/dom_xinclude/include2.xml: - * examples/dom_xinclude/main.cc: New files. - * libxml++/document.[h|cc]: Add process_xinclude(). - * libxml++/libxml++.h: Add new header files. - * libxml++/nodes/node.cc: create_wrapper(): Create XIncludeStart and - XIncludeEnd nodes. - * libxml++/nodes/xincludeend.[h|cc]: - * libxml++/nodes/xincludestart.[h|cc]: New files. - * .gitignore: Ignore /examples/dom_xinclude/dom_xinclude. Bug #338521. - -2012-08-28 Kjell Ahlstedt - - Parser: Make it thread-safe. - - * configure.ac: Require glibmm-2.4 >= 2.32.0. - * libxml++/parsers/parser.cc: Protect all accesses to extra_parser_data with - a Glib::Threads::Mutex. Bug #681467. - -2012-08-10 Kjell Ahlstedt - - Document: Make the Document(xmlDoc*) constructor public. - - * libxml++/document.h: Make the Document(xmlDoc*) constructor public. - Remove friend declarations that become unnecessary. Bug #668980. - -2012-08-09 Kjell Ahlstedt - - Improve the DtdValidation and SchemaValidation example programs. - - * examples/dtdvalidation/main.cc: - * examples/schemavalidation/main.cc: Print all information from all thrown - xmlpp exceptions. - -2012-08-09 Kjell Ahlstedt - - Validators: Improve the error handling. - - * libxml++/validators/validator.[h|cc]: - * libxml++/validators/dtdvalidator.[h|cc]: - * libxml++/validators/schemavalidator.[h|cc]: Check more return codes from - libxml2 functions. Improve the description of member functions in the - reference documentation. Bug #635846. - -2012-08-07 Kjell Ahlstedt - - Add incremental parsing to the SaxParser example program. - - * examples/sax_parser/main.cc: Uncomment and correct the code that shows - incremental parsing with SaxParser::parse_chunk(). - -2012-08-07 Kjell Ahlstedt - - Parsers: Improve the error handling. - - * libxml++/parsers/domparser.[h|cc]: - * libxml++/parsers/saxparser.[h|cc]: - * libxml++/parsers/textreader.[h|cc]: Check more return codes from libxml2 - functions. Improve the description of errors in the reference documentation. - Bug #635846. - -2012-08-07 Kjell Ahlstedt - - Document, Element, Node: Remove unnecessary tests for null pointers. - - * libxml++/document.cc: - * libxml++/nodes/element.cc: - * libxml++/nodes/node.cc: Remove tests for null pointer before calling - xmlFreeNode(), which does nothing if given a null pointer. These unnecessary - tests were newly added when error handling was improved. Bug #635846. - -2012-08-05 Kjell Ahlstedt - - Schema::set_document(): Create empty document. - - * libxml++/schema.[h|cc]: set_document(): If the argument 'document' is 0, - create an empty document, as the documentation says. - -2012-08-05 Kjell Ahlstedt - - Document, Schema: Improve the error handling. - - * libxml++/document.[h|cc]: - * libxml++/schema.[h|cc]: Check more return codes from libxml2 functions. - Improve the description of errors in the reference documentation. Bug #635846. - -2012-08-02 Kjell Ahlstedt - - Element, Node: Improve the error handling. - - * libxml++/nodes/element.[h|cc]: - * libxml++/nodes/node.[h|cc]: Check more return codes from libxml2 functions. - Improve the description of errors in the reference documentation. Bug #635846. - -2.35.3: - -2012-06-19 Kjell Ahlstedt - - Add examples/Makefile.am. Let 'make check' run the examples. - - * examples/Makefile.am: New file. Let 'make check' both compile and run the - example programs. - * Makefile.am: Call examples/Makefile. Move all 'examples' stuff to - examples/Makefile.am. - * configure.ac: Remove --enable-examples. Generate examples/Makefile. - * .gitignore: Ignore make-check-sh. Bug #678390. - -2012-06-19 Kjell Ahlstedt - - Example programs: Fix return codes and print errors on std::cerr. - - * examples/*/main.cc: Return EXIT_FAILURE in case of failure. Print error - messages on std::cerr. The example programs can then be run by 'make check'. - Bug #678390. - -2012-04-20 Kjell Ahlstedt - - Node: Add functions eval_to_[boolean|number|string](). - - * examples/dom_xpath/example.xml: Add an element with numeric value. - * examples/dom_xpath/main.cc: Add calls to the new functions. - * libxml++/nodes/node.[h|cc]: - Add the functions eval_to_[boolean|number|string](). Bug #316244. - -2012-04-19 Kjell Ahlstedt - - Node: Make the previous fix thread-safe. - - * libxml++/nodes/node.cc: Delete the C++ wrapper of a deleted attribute node - without using xmlDeregisterNodeDefault. Bug #672992 comments 9-12. - -2012-04-19 Kjell Ahlstedt - - Node: Fix memory problems in import_node(). - - * libxml++/nodes/node.[h|cc]: Return added_node instead of imported_node, - which libxml2 may delete. Delete the C++ wrapper of a deleted attribute node. - * examples/import_node/example[1|2].xml: - * examples/import_node/main.cc: Import attributes and a text node which is - merged with an existing text node. Bug #672992. - -2012-04-12 Kjell Ahlstedt - - Define LIBXMLCPP_EXCEPTIONS_ENABLED unconditionally. - - * configure.ac: Add AC_DEFINE([LIBXMLCPP_EXCEPTIONS_ENABLED],[1],... - -2012-03-30 Murray Cumming - - Node: Check for a null pointer, to fix a scan-build warning. - - * libxml++/nodes/node.cc: This seems unlikely. - -2.35.2: - -2012-03-21 Murray Cumming - - Fix a warning found by clang++ - - * libxml++/parsers/textreader.h: PropertyReader is a class, not - a struct. - -2012-03-20 Murray Cumming - - Remove the --disable-api-exceptions configure option. - - And remove the #ifdefs and #else blocks from the code. - This is not used by anybody now, as far as I know, so this makes the - code easier to maintain. - -2012-03-20 Murray Cumming - - A fix for the previous commit. - - * libxml++/nodes/node.cc: get_first_child() const: Use the name - parameter. - -2012-03-19 Murray Cumming - - Node: Add get_first_child(). - - * libxml++/nodes/node.[h|cc]: This is like get_children(), - but it returns only the first node, optionally returning - the first one with a certain name. - Based on a patch by Ilya Murav'jov in bug #648125 . - -2.35.1: - -2012-02-15 Kjell Ahlstedt - - Handle attributes with default values correctly. - - * libxml++/attributedeclaration.[h|cc]: - * libxml++/attributenode.[h|cc]: New files. - * Makefile.am: - * libxml++/Makefile.am: Add the new files. - * libxml++/libxml++.h: Add the new .h files. - * docs/manual/libxml++_without_code.xml: Add AttributeDeclaration and - AttributeNode in the list of node classes. - * libxml++/attribute.[h|cc]: Make get_value() useful also for default values - (XML_ATTRIBUTE_DECL). Fix set_value() for attributes in a namespace. - * libxml++/nodes/element.[h|cc]: get_attribute(): Add description. Don't use - xmlHasProp(), it ignores namespace. - * libxml++/nodes/node.cc: get_namespace_prefix(), get_namespace_uri(), - set_namespace(), create_wrapper(): Add code for XML_ATTRIBUTE_DECL. - * examples/dom_parser/example.dtd: Add attribute 'title' with default value. - * examples/dom_parser/example.xml: Add attribute 'title' with explicit value. - Bug #669635. - -2012-02-15 Kjell Ahlstedt - - Node: Correct mis-spelt LIBXMLCPP_EXCEPTIONS_ENABLED. - - * libxml++/nodes/node.h: Add some "@throws exception". - * libxml++/nodes/node.cc: Change LIBXMLCPP_EXCEPTIONS_ENABLE to - LIBXMLCPP_EXCEPTIONS_ENABLED in find_impl() and set_namespace(). - -2012-02-15 Kjell Ahlstedt - - Improved handling of entity references and processing instructions. - - * libxml++/nodes/entitydeclaration.[h|cc]: New files. - * Makefile.am: - * libxml++/Makefile.am: Add the new files. - * libxml++/libxml++.h: Add the new .h file. - * docs/manual/libxml++_without_code.xml: Add EntityDeclaration in the list - of node classes. - * libxml++/document.[h|cc]: Add add_processing_instruction(). - * libxml++/nodes/element.[h|cc]: Add add_child_entity_reference() and - add_child_processing_instruction(). - * libxml++/nodes/entityreference.h: Improve the description of - get_resolved_text() and get_original_text(). - * libxml++/nodes/node.cc: get_namespace_prefix() and get_namespace_uri(): - XML_ENTITY_DECL has no namespace. Don't try to find it. - create_wrapper(): Create an EntityDeclaration when type == XML_ENTITY_DECL. - free_wrappers(): Don't walk the child list when type == XML_ENTITY_REF_NODE. - * examples/dom_build/main.cc: Add entity declarations and references, and - processing instructions to the built xml file. - * examples/dom_parse_entities/example.dtd: Make it compatible with example.xml. - * examples/dom_parse_entities/example.xml: Add an entity definition that - contains entity references. - * examples/dom_parse_entities/main.cc: Print the parsed file both with and - without entity substitution. - * examples/dom_parser/example.dtd: Make it compatible with example.xml. - * examples/dom_parser/main.cc: Add command flag -E (Don't substitute entities). - Bug #669481 - -2012-02-15 Kjell Ahlstedt - - Add some files to .gitignore. - - * .gitignore: Add docs files that are copied from mm-common. - Add /MSVC_Net2010/libxml++/libxml++.rc and - /examples/dom_read_write/example_output.xml. - -2012-02-15 Kjell Ahlstedt - - Add @newin{2,36} to some new functions where it's missing. - - * libxml++/exceptions/exception.h: Add @newin{2,36} to format_xml_error() and - format_xml_parser_error(). - * libxml++/parsers/parser.h: Add @newin{2,36} to [set|get]_throw_messages(). - Bug #304020. - -2012-02-10 Kjell Ahlstedt - - Make the schema validation example program work with no arguments. - - * examples/schemavalidation/main.cc: Correct the test for number of arguments. - -2012-01-30 Kjell Ahlstedt - - Parser: Throw more detailed error messages. - - * examples/dom_parser/main.cc: Add command parameters -v -e -t. - * libxml++/exceptions/exception.[h|cc]: Add format_xml_error() and - format_xml_parser_error(). - * libxml++/parsers/domparser.cc: Call format_xml_error() and - format_xml_parser_error() to get more detailed messages in exceptions. - * libxml++/parsers/parser.[h|cc]: Add [set|get]_throw_messages() and (local in - .cc until ABI can be broken) on_parser_[error|warning](). Bug #304020. - -2012-01-30 Murray Cumming - - Document: Make the Document(xmlDoc*) constructor protected. - - * libxml++/document.h: This was requested in bug #668980 (A. Pignotti). - -2011-09-09 Murray Cumming - - Document: write_to_*(): Make sure that we write UTF-8 out. - - * libxml++/document.cc: Because the xmlDocDump*() functions use some other - encoding if you specify NULL, causing errors such as: - xmlEscapeEntities : char out of range - -2.34.2: - -2011-09-06 Mathias Lorente - - Node::create_new_child_node(): Use the default namespace if none is specified. - - * libxml++/nodes/node.cc: This is better than just ignoring it. - Bug #656110 - -2011-07-20 Murray Cumming - - ContentNode::get_content(): Fix a documentation typo. - - * libxml++/nodes/contentnode.h: Mention > instead of &qt (a q - instead of a g, and no ;.). - -2011-07-20 Mathias Lorente - - Add Element::add_child_cdata(). - - * libxml++/nodes/element.[h|cc]: Add add_child_cdata(), using - xmlNewCDataBlock(), like the existing add_child_text(). - * examples/sax_parser_build_dom/example.xml: - * examples/sax_parser_build_dom/svgparser.[h|cc]: Use the new API. - -2.34.1: - -2011-04-17 Murray Cumming - - Fix distcheck. - - * Makefile.am: Specify the full path to docbook-customisation.xsl, - which is apparently necessary with the autotools that I have here. - -2011-04-17 Murray Cumming - - Fix the build with --enable-warnings=fatal. - - * configure.ac: Use -no-long-long to avoid an (apparently new) compiler - warning about long long not being supported by C++98. glibmm already had - this option. - -2011-04-17 Murray Cumming - - Do not require mm-common during the tarball build. - - * configure.ac: Add a MM_CONFIG_DOCTOOL_DIR() call. - -2.34.0: - -2011-02-24 Murray Cumming - - Fix the build with the changed linker behaviour on Ubuntu Natty. - - * Makefile.am: Link the examples to glibmm explicitly. - -2.33.2: - -2011-02-11 Murray Cumming - - Node::remove_child(): Fix a use of deleted memory - - * libxml++/nodes/node.cc: - Use a temporary variable to avoid accessing the node C++ instance after we - have deleted it. Valgrind foudn this. - Also remove the comment about the libxml deleting our C++ instance via a - callback, because we don't do that anymore. - -2010-11-26 Murray Cumming - - Check some libxml function return values. - - * libxml++/document.cc: do_write_to_stream(): - * libxml++/schema.cc: set_document(): Check the results from - xmlSchemaNewDocParserCtxt() and xmlSaveFormatFileTo(). - Bug #635846 (Markus Elfring). - -2.33.1: - -2010-11-14 Murray Cumming - - free_wrappers(): Fix crash. - - * libxml++/nodes/node.cc: free_wrappers(): Revert my change to check - xmlNode::properties for all types, because the layout of some structs - is apparently completely different (not really deriving fully), and this - caused a crash in examples/sax_parser/. - Added an explanatory comment. - -2010-11-14 Murray Cumming - - Change the --enable-examples default to yes. - - * configure.ac: Build the examples by default, so we at least check the - build more often. Disabling them is only useful for package building, - which is the less common case. - -2010-11-14 Murray Cumming - - Moved create_wrapper() and free_wrappers() to Node. - - * libxml++/document.[h|cc]: - * libxml++/nodes/node.[h|cc]: Moved create_wrapper() and free_wrappers() - to here from Document. - free_wrappers(): Never return inside the switch/case, so we check - xmlNode::properties for all struct types, and to avoid making the behaviour - non-obvious. - * libxml++/parsers/textreader.cc: - * libxml++/validators/dtdvalidator.cc: - * libxml++/nodes/element.cc: Adapted. - -2010-11-08 Alessandro Pignotti - - Make libxml++ compatible with separate and multi-threaded libxml2 usage. - - * libxml++/document.[h|cc]: Added create_wrapper() and free_wrappers(), - replacing on_libxml_construct() and on_libxml_destruct() . - Init(): Do not register these global callbacks with libxml. - * libxml++/nodes/element.cc: - * libxml++/nodes/node.[h|cc]: - * libxml++/parsers/textreader.cc: - * libxml++/validators/dtdvalidator.cc: Call these create_wrapper() before - ever trying to get a C++ instance from a C instance. Call free_wrappers() - in destructors and other places where we want the instance to be destroyed. - - This avoids use of libxml's global function pointers, which are not - thread-safe. - -2010-11-08 Murray Cumming - - Do not call xmlCleanupParser() because it is brutal. - - * libxml++/document.cc: ~Init(): Do not call xmlCleanupParser() because it - breaks libxml generally and should only be called by an application - explicitly before it ends, for instance at the end of its main(). - -2010-10-19 Knut Aksel Røysland - - Node::get_parent(): Removed code duplication. - - * libxml++/nodes/node.cc: get_parent() const: Use const_cast<> to call - the non-const version, instead of duplicating the code. - -2.32.0: - -2010-10-14 Murray Cumming - - website: Change the mailing list location, because I moved it. - - * docs/index.html: The mailing list is now at gnome.org. - -2010-10-03 Armin Burgmeier - - * MSVC_Net2005/README: - * MSVC_Net2005/examples/dom_build/dom_build.vcproj: - * MSVC_Net2005/examples/dom_parse_entities/dom_parse_entities.vcproj: - * MSVC_Net2005/examples/dom_parser/dom_parser.vcproj: - * MSVC_Net2005/examples/dom_parser_raw/dom_parser_raw.vcproj: - * MSVC_Net2005/examples/dom_read_write/dom_read_write.vcproj: - * MSVC_Net2005/examples/dom_xpath/dom_xpath.vcproj: - * MSVC_Net2005/examples/dtdvalidation/dtdvalidation.vcproj: - * MSVC_Net2005/examples/import_node/import_node.vcproj: - * MSVC_Net2005/examples/sax_exception/sax_exception.vcproj: - * MSVC_Net2005/examples/sax_parser/sax_parser.vcproj: - * MSVC_Net2005/examples/sax_parser_build_dom/sax_parser_build_dom.vcproj: - * MSVC_Net2005/examples/sax_parser_entities/sax_parser_entities.vcproj: - * MSVC_Net2005/examples/schemavalidation/schemavalidation.vcproj: - * MSVC_Net2005/examples/textreader/textreader.vcproj: - * MSVC_Net2005/gendef/gendef.vcproj: - * MSVC_Net2005/libxml++.sln: - * MSVC_Net2005/libxml++/libxml++.vcproj: - * MSVC_Net2008/README: - * MSVC_Net2008/examples/dom_build/dom_build.vcproj: - * MSVC_Net2008/examples/dom_parse_entities/dom_parse_entities.vcproj: - * MSVC_Net2008/examples/dom_parser/dom_parser.vcproj: - * MSVC_Net2008/examples/dom_parser_raw/dom_parser_raw.vcproj: - * MSVC_Net2008/examples/dom_read_write/dom_read_write.vcproj: - * MSVC_Net2008/examples/dom_xpath/dom_xpath.vcproj: - * MSVC_Net2008/examples/dtdvalidation/dtdvalidation.vcproj: - * MSVC_Net2008/examples/import_node/import_node.vcproj: - * MSVC_Net2008/examples/sax_exception/sax_exception.vcproj: - * MSVC_Net2008/examples/sax_parser/sax_parser.vcproj: - * MSVC_Net2008/examples/sax_parser_build_dom/sax_parser_build_dom.vcproj: - * MSVC_Net2008/examples/sax_parser_entities/sax_parser_entities.vcproj: - * MSVC_Net2008/examples/schemavalidation/schemavalidation.vcproj: - * MSVC_Net2008/examples/textreader/textreader.vcproj: - * MSVC_Net2008/gendef/gendef.vcproj: - * MSVC_Net2008/libxml++.sln: - * MSVC_Net2008/libxml++/libxml++.vcproj: - * MSVC_Net2010/README: - * MSVC_Net2010/examples/dom_build/dom_build.vcxproj: - * MSVC_Net2010/examples/dom_build/dom_build.vcxproj.filters: - * MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj: - * MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj.filters: - * MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj: - * MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj.filters: - * MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj: - * MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj.filters: - * MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj: - * MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj.filters: - * MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj: - * MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj.filters: - * MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj: - * MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj.filters: - * MSVC_Net2010/examples/import_node/import_node.vcxproj: - * MSVC_Net2010/examples/import_node/import_node.vcxproj.filters: - * MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj: - * MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj.filters: - * MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj: - * MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj.filters: - * MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj: - * MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj.filters: - * MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj: - * MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj.filters: - * MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj: - * MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj.filters: - * MSVC_Net2010/examples/textreader/textreader.vcxproj: - * MSVC_Net2010/examples/textreader/textreader.vcxproj.filters: - * MSVC_Net2010/gendef/gendef.cc: - * MSVC_Net2010/gendef/gendef.vcxproj: - * MSVC_Net2010/gendef/gendef.vcxproj.filters: - * MSVC_Net2010/libxml++.sln: - * MSVC_Net2010/libxml++/libxml++.rc.in: - * MSVC_Net2010/libxml++/libxml++.vcxproj: - * MSVC_Net2010/libxml++/libxml++.vcxproj.filters: - * Makefile.am: - * configure.ac: Added support for MSVC 2010 and 64 bit. - -2010-06-13 Murray Cumming - - Node::find(): Check xmlNode::type for a XML_NAMESPACE_DECL. - - * libxml++/nodes/node.cc: find_impl(): if the xmlNode has type - XML_NAMESPACE_DECL then it is actually a xmlNs, which is not like a xmlNode - at all (thanks to the awful undocumented libxml++ system of struct - inheritance). - So we just igore these items. We need to decide what the caller really - expects. - -2010-06-13 Murray Cumming - - Node::find(): Revert some of my previous change because it breaks some code. - - * libxml++/nodes/node.cc: find_impl(): Restore the previous behaviour, - because the strange use of _private only seems to happen sometimes. - -2010-06-13 Murray Cumming - - Node::find(): Cope with weird use of _private in xmlNodeSet. - - * libxml++/nodes/node.cc: The xmlNodeSet seems to contain extra xmlNodes that - were never given to on_libxml_construct(). Those xmlNodes seem to abuse - private_, where we find our real xmlNodes containing our C++ Nodes. - This fixes bug #386013 (Max Kirillov) though it depends on undocumented - libxml behaviour. - -2010-06-13 Murray Cumming > - - Node::find(): Use libxml functions instead of direct C access. - - * libxml++/nodes/node.cc: Use xmlXPathNodeSetIsEmpty(), - xmlXPathNodeSetGetLength() and xmlXPathNodeSetItem() instead of direct - xmlNodeSet struct access. - -2010-06-13 Murray Cumming - - Manual: Use git.gnome.org as the link to the examples source code. - - * docs/manual/libxml++_without_code.xml: Use git.gnome.org for the examples - url base, as we do in gtkmm-documentation. - -2010-06-13 Murray Cumming - - Restore the mm-common make target and update a link. - - * Makefile.am: Restore (and update) the post-html target that was lost when - we redid the build system for mm-common. - * docs/index.html: Change the link to the manual to point to its new location - at library.gnome.org. - -2.30.1: - -2010-05-04 Murray Cumming - - Documentation: Don't hide undocumented API. - - * docs/reference/Doxyfile.in: Use the same options as gtkmm (mostly). - In particular, don't hide undocumented API, such as NodeSet, to fix - bug #583412 (Hubert Figuiere). - -2010-05-04 Murray Cumming - - Documentation: Improvements. - - * libxml++/libxml++.h: Expand the main page text, linking to the tutorial - and to important classes. - * libxml++/parsers/domparser.h: - * libxml++/schema.h: Correct the class descriptions. - * libxml++/parsers/textreader.h: Add a class description. - * libxml++/nodes/element.h: - * libxml++/nodes/node.h: - * libxml++/parsers/saxparser.h: - * libxml++/validators/schemavalidator.h: - Correct @newin2p2* to @newin{2,*} now that we use mm-common. - -2010-04-27 David King - - Further documentation main page improvements - - * libxml++/libxml++.h: Some minor improvements. - -2010-04-23 David King - - Documentation main page improvements - - * libxml++/libxml++.h: Add external links and compilation example. - -2010-04-16 David King - - Minor documentation update - - * docs/index.html: Link to latest gnome.org resources. - * libxml++/libxml++.h: Add minimal documentation for main page. - -2010-04-06 Murray Cumming - - .pc file: Add datarootdir. - - * libxml++-2.6.pc.in: Add datarootdir and datadir, as in the gtkmm .pc.in - file, because I started seeing this warning when running autogen.sh in Glom: - Variable 'datarootdir' not defined in '/opt/gnome228/lib/pkgconfig/libxml++-2.6.pc' - -2010-04-03 Armin Burgmeier - - * MSVC_Net2005/libxml++.sln: - * MSVC_Net2008/libxml++.sln: Add dom_parser_raw project to the - solution files. - -2010-03-30 Murray Cumming - - Stop exceptions when using std::cout and UTF-8. - - * examples/*/main.cc: Initialize the global C and C++ locale to prevent - exceptions when ouputing a ustring (with non-ASCII UTF-8) to std::cout. - We don't see this problem when writing gtkmm apps because gtk_init() (via - Gtk::Main) initializes the C locale correctly. - - Thanks to Daniel Elstner for the solution (he will document it properly - in the Glib::ustring API reference) and to Nic Reveles and others for - noticing the problem. - -2010-03-30 David King - - Update pkg-config file - - * libxml++-2.6.pc.in: Add documentation locations to pkg-config file. - Update other fields to use variables, rather than hardcoded values. - -=== 2.30.0 === - -2010-03-30 David King - - Disable AM_MAINTAINER_MODE by default - - * configure.ac: Pass the disable parameter to AM_MAINTAINER_MODE so - that tarball users do not need doxygen, mm-common, etc. if they modify - files. Maintainer mode is still enabled if running autogen.sh. - -2010-03-29 David King - - Move a target outside a conditional block to fix the build - - * Makefile.am: Move docs/manual/libxml++.xml target outside the - ENABLE_DOCUMENTATION conditional block. - -2010-03-29 David King - - Use mm-common for reference documentation generation - - * .gitignore: Update. - - * Makefile.am: Remove SUBDIRS. Make examples build and documentation - build conditional. Build reference documentation with doc-reference.am - from mm-common. Add docs/manual/libxml++.pdf target, but do not enable - it by default. Add autogen.sh and docs/manual/insert_example_code.pl to - dist_noinst_SCRIPTS. Add docs/manual/html/*.html to - MAINTAINERCLEANFILES. - - * autogen.sh: Add --enable-maintainer-mode to arguments passed to - configure. - - * configure.ac: Add AM_MAINTAINER_MODE. Add a configure argument to - enable the build of the examples. Use mm-common macros to add a - configure argument to enable documentation, and use the glibmm - tagfile. Check for xmllint and db2latex for DTD validation of the - DocBook manual and building the PDF documentation, repectively. Remove - the last non-toplevel Makefiles from AC_CONFIG_FILES. - - * docs/Makefile.am: - * docs/Makefile_web.am_fragment: - * docs/manual/Makefile.am: - * docs/reference/Makefile.am: Remove from repository, and move content - to Makefile.am. - - * docs/manual/docbook-customisation.xsl: Add DocBook customisation - parameters. - - * docs/manual/libxml++_without_code.xml: Make validate. - - * docs/reference/Doxyfile.in: Update from mm-common. - - * docs/reference/README: Remove empty file. - -2010-03-27 David King - - Fix several compiler warnings - - * examples/dom_build/main.cc: - * examples/dtdvalidation/main.cc: - * examples/import_node/main.cc: - * examples/sax_exception/main.cc: - * examples/sax_exception/my_parser.cc: - * examples/sax_parser/main.cc: - * examples/sax_parser/my_parser.cc: - * examples/sax_parser_build_dom/svgparser.cc: - * examples/sax_parser_entities/myparser.cc: - * examples/textreader/main.cc: - * libxml++/parsers/textreader.cc: Comment out unused parameters and - variables. - - * libxml++/parsers/saxparser.cc: Fill in missing fields of - xmlSAXHandler struct. - -2010-03-27 David King - - Refactor build system - - * Makefile.am: Merge from subdir Makefile.am files, excluding doc. - - * MSVC_Net2005/examples/dom_parser_raw/dom_parser_raw.vcproj: - * MSVC_Net2008/examples/dom_parser_raw/dom_parser_raw.vcproj: Add - missing Visual studio project files. - - * MSVC_Net2005/examples/*/Makefile.am: - * MSVC_Net2005/examples/Makefile.am: - * MSVC_Net2005/gendef/Makefile.am: - * MSVC_Net2005/libxml++/Makefile.am: - * MSVC_Net2008/examples/*/Makefile.am: - * MSVC_Net2008/examples/Makefile.am: - * MSVC_Net2008/gendef/Makefile.am: - * MSVC_Net2008/libxml++/Makefile.am: Remove from repository, and move - content to Makefile.am, making the MSVC project file build - non-recursive. - - * README: Update. - - * autogen.sh: Copy from gtkmm. - - * configure.in: Move to configure.ac. - - * configure.ac: Require autoconf 2.59 and automake 1.9. Use new-style - AC_INIT() with bug-report link and homepage URL. Use mm-common for - initialisation of version variables. Require libtool 2.2.6 for much - faster builds. Use MM_ARG_ENABLE_WARNINGS to configure compiler - warning flags. Use MM_CHECK_PERL to check for the required Perl - version. Use AC_CONFIG_FILES rather than AC_OUTPUT. Update for - Makefile.am changes. - - * config.h.in: Remove from repository, as autoheader is now used. - - * */.cvsignore: Remove old files. - - * doc/manual/Makefile.am: Use the correct Perl. - - * doc/reference/Doxyfile.in: - * MSVC_Net2005/libxml++/libxml++.rc.in: - * MSVC_Net2008/libxml++/libxml++.rc.in: Use new-style variable names. - - * examples/Makefile.am_fragment: - * examples/Makefile.am: - * examples/*/Makefile.am: Remove from repository, and move content to - Makefile.am, making the examples build non-recursive. - - * .gitignore: Update. - - * libxml++/Makefile.am: - * libxml++/*/Makefile.am: Remove from repository, and move content to - Makefile.am, making the libxml++ build non-recursive. - - * libxml++.spec.in: - * INSTALL: Remove from repository. - - * scripts/README: - * scripts/Makfile.am: Remove from repository. - - * scripts/reduced.m4: Move to macros/reduced.m4 - -2010-03-08 Murray Cumming - - Use 0 instead of NULL. - - * MSVC_Net2005/gendef/gendef.cc: - * MSVC_Net2008/gendef/gendef.cc: - * libxml++/attribute.cc: - * libxml++/document.cc: - * libxml++/io/outputbuffer.cc: - * libxml++/io/parserinputbuffer.cc: - * libxml++/nodes/node.cc: - * libxml++/parsers/domparser.cc: - * libxml++/parsers/parser.cc: - * libxml++/parsers/textreader.cc: - * libxml++/schema.cc: - * libxml++/schema.h: Do not use NULL. It is unwise in C++. - -=== 2.26.1 === - -2009-07-27 Johannes Schmid - - * libxml++/validators/schemavalidator.cc: - * libxml++/schema.cc: Fixed exception handling - problems in non-exception build - * examples/sax_parser/myparser.cc/h: Make example build withouth exceptions, - it's useless then though - * examples/schemavalidation/main.cc: Fixed build without exceptions - -2009-07-27 Johannes Schmid - - New tarball release - - * configure.in: Updated version to 2.26.1 - * NEWS: updated - -2009-05-07 Murray Cumming - - Fix the build without exceptions, hopefully. - - * libxml++/parsers/textreader.cc: check_for_exceptions(): - Add an ifdef so that this should build with exceptions disabled, - though there is no alternative API yet. Noticed by David King. - -2009-05-07 Murray Cumming - - * libxml++/parsers/textreader.cc: Whitespace corrections. - -2009-03-25 Hubert Figuiere - - * libxml++/parsers/saxparser.h: Fix some warnings triggered - by -Wshadow. - -2009-03-23 Hubert Figuiere - - * libxml++/parsers/textreader.cc: severity_ was not initialised - at construction time. (Closes #576516) - -2.26.0: - -2009-03-16 Murray Cumming - - * configure.in: Increased version number to match GNOME 2.26. - -2.24.3: - -2009-03-02 Armin Burgmeier - - * libxml++/validators/validator.h: - * libxml++/parsers/parser.h: Removed the vsnprintf #define on Windows. - This could conflict with another define otherwise. Both MSVC and MinGW - have vsnprintf (without underscore) as well, and I verified libxml++ - still compiles in both. If we still need the definition for some - reason, then we should re-add it into the source files, so that other - libraries don't conflict with our definition. - -2009-01-09 Stef Walter - - * libxml++/parsers/textreader.[h|cc]: Add setup_exceptions(), setting - the on_libxml_error() callback, and call it from the constructors. - check_for_exceptions(): Actually check some member variables and throw an - exception if necessary. - This should fix bug #348006. - It breaks ABI because it adds member variables, but we decided that is - OK because nobody could actually be using this class seriously before - now because it had no error checking. - -2.24.2: - -2008-12-20 Armin Burgmeier - - * libxml++/schema.cc (set_document): Set embedded_doc_ according to - the embed parameter instead of always setting it to false, so that we - actually release the document in release_underlying(). - (release_underlying): Free the schema in all cases, also when the - document was not embedded, to avoid a memory leak. - - * libxml++/validators/schemavalidator.cc (parse_file, parse_memory, - parse_document): Make sure not to leak the xmlSchemaParserCtxtPtr in - case of an exception. Bug #563321, Arjan Franzen. - -2008-12-18 Armin Burgmeier - - * win32_msvc6/: - * Makefile.am: - * configure.in: Removed outdated MSVC6 project. - -2.24.1: - -2008-12-12 Armin Burgmeier - - * MSVC_Net2008/examples/sax_parser/sax_parser.vcproj.HALLWA.Armin.user: - Removed this generated file. It went in by accident. - - * MSVC_Net2008/examples/sax_parser/sax_parser.vcproj: Added the - example project file instead, which should have been added from the - beginning. - -2008-12-12 Armin Burgmeier - - * MSVC_Net2005/libxml++/libxml++.vcproj: - * MSVC_Net2008/libxml++/libxml++.vcproj: Added schema.cc and - schemavalidator.cc to the project. Bug #563664 (Arjan Franzen). - - * MSVC_Net2005/examples/schemavalidation/schemavalidation.vcproj: - * MSVC_Net2005/examples/schemavalidation/Makefile.am: - * MSVC_Net2005/examples/Makefile.am: - * MSVC_Net2005/libxml++.sln: Added the schema validator example to the - MSVC8 solution file. - - * MSVC_Net2008/examples/schemavalidation/schemavalidation.vcproj: - * MSVC_Net2008/examples/schemavalidation/Makefile.am: - * MSVC_Net2008/examples/Makefile.am: - * MSVC_Net2008/libxml++.sln: Added the schema validator example to the - MSVC9 solution file. - -2008-12-12 Przemysław Grzegorczyk - - * libxml++/schema.cc: Fix a typo to fix the build. - -2008-12-08 Murray Cumming - - * libxml++/validators/validator.cc: check_for_exception(): Use an - auto_ptr<> to avoid leaking the exception, as in - Parser::check_for_exception(). - Bug #563321 (Arjan Franzen) - -2008-12-05 Murray Cumming - - * libxml++/schema.cc: release_underlying(): Use xmlSchemaFree() - to avoid a leak, as suggested by Balazs Tirpak. Bug #312216. - -2008-10-09 Armin Burgmeier - - * MSVC_Net2005/*/*.vcproj: Adapt the new DLL naming convention. - - * MSVC_Net2008/: Added project files for Visual Studio 2008. - - * Makefile.am: - * configure.in: Added the new files to the distribution. - -2.24.0: - - * configure.in: Increased version to match GNOME 2.24: - -2.23.3: - -2008-08-16 Murray Cumming - - * libxml++/attribute.cc: get_value(): xmlGetNsProp() takes the - namespace URI, not the prefix. - Bug #547689 (Sergei Fedorov) - -2008-08-14 Murray Cumming - - * examples/dom_parser/Makefile.am: - * examples/dom_parser/example_with_namespace.xml: - Added an example using namespace prefixes, from bug - #547689. - * examples/dom_parser/main.cc: Comment out the call to set_validate(), - because that example does not have a DTD. - Show the namespace prefixes in the output. - * libxml++/attribute.cc: get_value(): Use xmlGetNsProp() instead of - xmlGetProp(), so we don't ignore the namespace prefix, so we get - the correct value. - Bug #547689 (Sergei Fedorov) - -2008-08-10 Armin Burgmeier - - * MSVC_Net2005/: Renamed from MSVC_Net2003. - - * MSVC_Net2005/libxml++/libxml++.vcproj: Link against libxml2.lib - instead of xml2.lib because that's how it is called in Tor's GTK+ - bundle. - - * MSVC_Net2005/libxml++/libxml++.rc.in: Removed "#include resource.h" - because there is no resource.h. - - * MSVC_Net2005/libxml++/libxml++.sln: Build all examples by default. - - * Makefile.am: - * configure.in: Adapt build files for the MSVC_Net2003 -> MSVC_Net2005 - rename. - -2.23.2: - -2008-05-05 Murray Cumming - - * examples/sax_parser/main.cc (main): Use parse_file() but leave - the parse_chunk() version commented out, to simplify this example. - * examples/sax_parser/myparser.cc - Catch Glib::ConvertError exceptions when using std::cout, though - libxml++ should really always supply valid UTF-8 to us. - -2008-04-14 Armin Burgmeier - - * libxml++/parsers/saxparser.h: - * libxml++/parsers/saxparser.cc: Added a parse_chunk_raw() method and - changed parse_chunk() to use it. - -2.23.1: - -2008-03-26 Murray Cumming - - * examples/schemavalidation/Makefile.am: Corrected a filename to - fix distcheck - * libxml++/schema.h: - * libxml++/validators/schemavalidator.h: Added the newin2p24 doxygen - keyword. - -2008-03-26 Emilien KIA - - * configure.in: - * libxml++/Makefile.am: - * libxml++/libxml++.h: - * libxml++/schema.cc: - * libxml++/schema.h: Added Schema class, similar to the existing Dtd - class. - * libxml++/validators/Makefile.am: - * libxml++/validators/schemavalidator.cc - * libxml++/validators/schemavalidator.h: Added Schema validator class, - similar to the existing DtdValidator class. - - * examples/Makefile.am: - * examples/schemavalidation/: New example, similar to the - existing dtdvalidation example. - - Bug #312216. - -2008-03-26 Murray Cumming - - * docs/Makefile.am: Fixed the post-html rule. - * docs/index.html: Corrected some links. - * libxml++/nodes/node.h: Corrected documentation for the new methods - from the previous commit. - -2008-03-26 Murray Cumming - - * libxml++/nodes/element.cc: - * libxml++/nodes/element.h: Added add_child_text() with a previous_node - parameter, for adding between existing nodes. - Added add_child_text_before() too. - * libxml++/nodes/node.cc: - * libxml++/nodes/node.h: Added add_child() with a previous_node - parameter, for adding between existing nodes. - Added add_child_before() too. - - * docs/index.html: Removed the license clarifications text because I - always found it to be arbitrary and not very informative. - * docs/reference/Doxyfile.in: Added a newin2p24 doxygen keyword. - * docs/reference/Makefile.am: Do not create a version-specific - directory name for reference documentation. The Since: text and links - in the documentation are enough to know what was in what version. - -This is the svn trunk branch. See also the gnome-2-22 branch. - -2.22.0: - -2008-03-07 Deng Xiyue - - * libxml++/document.cc: - * libxml++/document.h: Add a destructor - (does not break ABI because the base class already has a - virtual destructor) that calls xmlCleanupParser to match the - existing call to xmlInitParser() in the constructor. Fixes - a memory leak. - Bug #501168 (Matt G.) - -2008-01-17 Roland Stigge - - * libxml++/attribute.cc: - * libxml++/dtd.cc: - * libxml++/dtd.h: - * libxml++/io/ostreamoutputbuffer.h: - * libxml++/io/outputbuffer.h: - * libxml++/keepblanks.cc: - * libxml++/keepblanks.h: - * libxml++/libxml++.h: - * libxml++/nodes/cdatanode.cc: - * libxml++/nodes/cdatanode.h: - * libxml++/nodes/commentnode.cc: - * libxml++/nodes/commentnode.h: - * libxml++/nodes/contentnode.cc: - * libxml++/nodes/element.cc: - * libxml++/nodes/element.h: - * libxml++/nodes/entityreference.cc: - * libxml++/nodes/entityreference.h: - * libxml++/nodes/node.cc: - * libxml++/nodes/processinginstructionnode.cc: - * libxml++/nodes/processinginstructionnode.h: - * libxml++/nodes/textnode.cc: - * libxml++/nodes/textnode.h: - * libxml++/parsers/domparser.cc: - * libxml++/parsers/domparser.h: - * libxml++/parsers/parser.cc: - * libxml++/parsers/parser.h: - * libxml++/parsers/saxparser.cc: - * libxml++/parsers/textreader.h: - Correct the name of the files in their comment blocks, - though this could just be removed instead. - Bug #510056. - -2008-01-17 Martin Michlmayr > - - * libxml++/parsers/parser.cc: - * libxml++/parsers/textreader.h: - Added includes to fix the build with gcc 4.3 - pre-releases. - Bug #510053. - -2.20.0: - -2007-08-30 Murray Cumming - - * examples/dom_parser_raw/main.cc: When exceptions are disabled, assume that they are also - disabled in glibmm and then use the extra error parameter to Glib::convert(), to fix the - build when using glibmm with disabled exceptions. - * docs/manual/Makefile.am: Use maintainer-clean instead of clean-local to delete the html, - but this still seems to be deleted when building debian packages. - -2.19.2: - -2007-08-29 Murray Cumming - - * scripts/Makefile.am: distcheck fixes. - -2007-08-29 Murray Cumming - - * autogen.sh: - * Makefile.am: - * configure.in: - * scripts/Makefile.am: - * scripts/reduced.m4: Added an --enable-api-exceptions - configure option, which defines LIBXMLCPP_EXCEPTIONS_ENABLED - in libxml++config.h. - * examples/dom_build/main.cc: - * examples/dom_parse_entities/main.cc: - * examples/dom_parser/main.cc: - * examples/dom_parser_raw/main.cc: - * examples/dom_read_write/main.cc: - * examples/dom_xpath/main.cc: - * examples/dtdvalidation/main.cc: - * examples/import_node/main.cc: - * examples/sax_exception/main.cc: - * examples/sax_exception/myparser.cc: - * examples/sax_parser/main.cc: - * examples/sax_parser_build_dom/main.cc: - * examples/sax_parser_entities/main.cc: - * examples/textreader/main.cc: - * libxml++/document.cc: - * libxml++/exceptions/exception.cc: - * libxml++/exceptions/internal_error.cc: - * libxml++/exceptions/parse_error.cc: - * libxml++/exceptions/validity_error.cc: - * libxml++/io/outputbuffer.cc: - * libxml++/io/parserinputbuffer.cc: - * libxml++/libxml++config.h.in: - * libxml++/nodes/contentnode.cc: - * libxml++/nodes/element.cc: - * libxml++/nodes/node.cc: - * libxml++/parsers/domparser.cc: - * libxml++/parsers/parser.cc: - * libxml++/parsers/saxparser.cc: - * libxml++/parsers/textreader.cc: - * libxml++/validators/dtdvalidator.cc: - * libxml++/validators/validator.cc: - Put LIBXMLCPP_EXCEPTIONS_ENABLED ifdefs around uses of - try, catch, and throw, so that libxml++ can build with - CXXFLAGS="-fno-exceptions". However, we might still - need some alternative error checking API. - -2.19.1: - -2007-07-30 Stef Walter - - * libxml++/nodes/element.cc: - * libxml++/nodes/element.h: Added get_attribute_value(), - to get a simple text value for an attribute, as a - convenience. - Patch in bug #373573. - -2007-07-30 Murray Cumming - - * docs/reference/Doxyfile.in: Added newin2p18, - newin2p20, and newin2p22 tags. - -This is the trunk branch for libxml++ 2.19/2.20. -See also the gnome-2-18 branch. - -2.18.2: - -2007-07-25 Christophe de Vienne - - * libxml++/parsers/textreader.cc: get_name(): - Fixed a memory leak. bug #447535. - -2.18.1: - -2007-06-10 Murray Cumming - - * libxml++/document.cc: add_comment(), - * libxml++/nodes/element.cc: add_child_text(): - add_child_comment(): Avoid accessing freed memory - when the text nodes are merged by xmlAddChild(). - -2.18.0: - -2007-02-10 Murray Cumming - - * examples/dom_parse_entities/main.cc: - * examples/dom_parser/main.cc: - * examples/dom_parser_raw/main.cc: - * examples/dom_read_write/main.cc: - * examples/dom_xpath/main.cc: - * examples/dtdvalidation/main.cc: - * examples/sax_parser/main.cc: - * examples/sax_parser_build_dom/main.cc: - * examples/sax_parser_entities/main.cc: Use std::string for file paths, - because we can not know the encoding of file paths. std::string therefore - means unknown encoding. - -2007-02-06 Artur Wegele - - * libxml++/parsers/parser.h: - * libxml++/validators/validator.h: Check for _MSC_VER instead - of WIN32 before setting MSVC++ pragmas, because that is apparently - more reliable. Bug #380110. - -2.17.2: - -2006-10-25 Nate Nielsen - - * libxml++/nodes/node.cc: - * libxml++/nodes/node.h: Node::get_next_sibling(), - Node::get_previous_sibling(). Bug #351867 - -2006-11-17 Nate Nielsen - - * libxml++/parsers/textreader.cc - * libxml++/parsers/textreader.h: Clean up TextReader() data - constructor signature. Removed '-1' as a special null terminated - value. This brings it inline with other parsers. - -2.17.1: - -2006-11-11 Nate Nielsen - - * libxml++/nodes/element.cc: Element::set_attribute(): - Fix redeclaration of variable in if-block. Bug #361950 - -2006-11-11 Nate Nielsen - - * libxml++/parsers/textreader.cc - * libxml++/parsers/textreader.h: TextReader() can now parse - memory buffers as well as files. Bug #351215 - -2006-11-11 Nate Nielsen - - * libxml++/nodes/node.cc: - * libxml++/nodes/node.h: Add Node::get_parent() Bug #351876 - -2006-04-24 Cedric Gustin - - * configure.in: Disable autoheader. - * config.h.in: New file. Added comments about the difference - between config.h.in and libxml++config.h.in. - -2006-04-21 Cedric Gustin - - * libxml++/Makefile.am: Added libxml++config.h.in to EXTRA_DIST. - -2006-04-21 Cedric Gustin - - * MSVC_Net2003/*.vcproj: Updated for Visual Studio 2005. Added the - /vd2 compiler flag (Bug #158040). Renamed target DLL to - xml++-2.6 to comply to the value returned by "pkg-config --libs - --msvc-syntax libxml++-2.6". - * MSVC_Net2003/libxml++.sln: Updated for Visual Studio 2005. - * MSVC_Net2003/gendef/gendef.cc: Redirect output of dumpbin to a - file. - * MSVC_Net2003/libxml++/Makefile.am: Get a local copy of the - libxml++config.h file created at configure time and distribute it - in the source tarball. - * libxml++/Makefile.am: Add -DLIBXMLPP_BUILD to the DEFS compiler - flags (switch between dllexport/dllimport on win32). Also install - libxml++config.h to $(prefix)/lib/libxml++-2.6/include. - * libxml++/*/*.Makefile.am: Add -DLIBXMLPP_BUILD to the DEFS - compiler flags (switch between dllexport/dllimport on win32). - * libxml++/exceptions/exception.h: Tag the xmlpp:exception classs - with LIBXMLPP_API to get rid of auto-import errors on win32 - (mingw32/cygwin). - * libxml++/libxml++config.h.in: New file. Define LIBXMLPP_API and - switch between dllimport and dllexport on win32. - * libxml++-2.6.pc.in: Add ${libdir}/libxml++-2.6/include to Cflags - (for libxml++config.h). - * configure.in: Added test for a native win32 platform. Use the - ms-bitfields on this platform only. Added the libxml++config.h - configuration file. - -2.14.0: - -2006-03-13 Christophe de Vienne - - * docs/index.html: Updated version number - -2006-03-13 Christophe de Vienne - - * NEWS, configure.in: Prepared release 2.14.0 - -2006-03-08 Murray Cumming - - * libxml++/nodes/contentnode.h: get_content() documentation: - Replace the TODO because I know know that apos is the fifth - predefined entity. - set_content(): Mention that the predefined entities are used - _where necessary_ because XML does not require use of quot or - apos in text nodes - just in attribute values. - -2.13.1: - -2005-12-20 Murray Cumming - - * docs/manual/libxml++_without_code.xml: Mention pkg-config. - -2005-12-16 Murray Cumming - - * libxml++/document.h: Minor grammar fixes in documentation. - * libxml++/nodes/node.h: Correct find() documentation slightly. - -2005-12-15 Robert Fleming - - * libxml++/nodes/node.cc: - * libxml++/nodes/node.h: Add find() overload that - takes namespaces to register, using xmlXPathRegisterNs(). - Bug #323935. - -2005-12-15 Murray Cumming - - * libxml++/nodes/node.cc: set_namespace(): Pass 0 to - xmlSearchNs() for empty (default) namespaces, instead of - an empty string, as we do elsewhere. This makes - Document::create_root_node() for when not specifying a - namespace. Bug #318186 from Erik Oestby. - -2005-12-15 Vadim Zeitlin - - * docs/reference/Doxyfile.in: Fix paths so buildir!=srcdir - builds work. Bug #319863. - -2005-09-21 Christophe de Vienne - - * libxml++.spec.in: Fixed include and .pc paths. Fixes #316827. - -This is the HEAD branch, for API additions. See also the gnome-2-12 branch. - -2.12.0: - -2005-08-26 Christophe de Vienne - - * libxml++/parsers/textreader.h: Added xmlReadState "Reading" as - suggested by Sebastian Moss. - -2.11.0: - -2005-08-25 YS - - * libxml++/Makefile.am: Changed link order to solve a link issue - on cygwin. Bug #314419. - -2005-06-13 Marek Rouchal - - * libxml++/io/istreamparserinputbuffer.cc: - * libxml++/io/istreamparserinputbuffer.h: - * libxml++/io/parserinputbuffer.cc: - * libxml++/io/parserinputbuffer.h: Remove extra ;s. - Bug #307481 - -2005-05-15 Murray Cumming - - * libxml++/document.h: Add comments about possibly deriving this - from Node, though it needs investigation, and we can not do this - in the stable API. - * libxml++/nodes/node.cc: get_namespace(), get_namespace_prefix(): - Return an empty string if the node is actually a Document, because - the underlying xmlDocument struct has no ns field. This should - prevent the crash in bug #161825. - -2005-05-15 Murray Cumming - - * docs/index.html: Add link to the LGPL text. - -2005-04-24 Murray Cumming - - * libxml++/parsers/domparser.cc: parse_context(): - Delete the context after, not before, checking it for an error. - Bug #156352 from Jim Garrison. - -2005-04-24 Murray Cumming - - * libxml++/parsers/saxparser.cc: SaxParserCallback::characters() - Call on_characters(), not on_cdata_block(), so that the correct - derived handler is called. Bug #301712 and patch from - Aaron Walker. - -2005-04-24 Murray Cumming - - * libxml++-2.6.pc.in: Remove -I for the include location of - a config file, because we don't install one. Bug #301727 - from Aaron Walker. - -2005-03-15 Murray Cumming - - * libxml++/document.cc: set_entity_declaration(): Pass 0 instead - of empty strings for the public ID and system ID, if an empty - string is provided. This stops libxml from using a useless empty - string. - -2005-03-09 Cedric Gustin - - * MSVC_Net2003/Makefile.am: Add blank.cpp to EXTRA_DIST. - * MSVC_Net2003/examples/*/*.vcproj: Change name of PDB file to - $(OutDir)/$(TargetName).pdb. - -This is the HEAD branch. - -2.10.0: - -2005-03-08 Christophe de Vienne - - * docs/reference/Makefile.am: Added one more rule so the "make - distcheck" works from a clean cvs working copy. - -2005-03-08 Christophe de Vienne - - * docs/manual/Makefile.am, docs/reference/Makefile.am: Added a few - rules so that "make dist" generated the documentation if it's - absent. - -2005-02-15 Murray Cumming - - * docs/manual/Makefule.am: Added insert_example_code to EXTRA_DIST, - though it should not be needed when building from a DIST anyway, - because we distribute the html. - -2.9.2: - -2005-02-13 Christophe de Vienne - - * docs/manual/Makefile.am: Removed README from EXTRA_DIST. - -2005-02-12 Christophe de Vienne - - * libxml++/nodes/node.cc: Fixed a little inefficency in find (#161925) - -2005-02-11 Murray Cumming - - * docs/: Added manual. - * configure.in: Use GLIBMM_CHECK_PERL to get the perl path, needed - to insert the example code in the manual. - * docs/Makefile.am: Move the reference and manual into a docs folder - so that the docs and the examples have the same relative path. - * docs/index.html: Mention the manual and update the links. - -2005-02-11 Murray Cumming - - * libxml++/document.cc: do_write_to_string(): libml returns the - number of bytes instead of the number of characters, so use the - appropriate ustring constructor, to avoid an exception later. - Bug found by Cyril Picard. - * docs/reference/Makefile.am: Install the reference documentation. - Distribute the built reference documentatoin, and Do not rebuild it - every time. - * docs/reference/Doxyfile.in: Generate doxygen tags so that other - documentation can link to the libxml++ documentation. Use the - libstdc++ and glibmm doxygen tags to link to their documentation, - for instance for Glib::ustring. - -2005-01-26 Cedric Gustin - - * MSVC_Net2003/README: Updated for 2.8.0 - -2005-01-26 Cedric Gustin - - * configure.in: parse micro version tags at configure time (for - libxml++.rc). Added support for shared libraries (DLL) on - win32. Added MSVC_Net2003 Makefiles. - * Makefile.am: Added MSVC_Net2003 subdir. - * libxml++/Makefile.am: Added linker flags for shared libraries - (DLL) on win32. - * examples/Makefile.am_fragment: Removed trailing slash in INCLUDES. - * MSVC_Net2003/*: Initial release. - -2.9.1: - -2004-12-25 Murray Cumming - - * libxml++/parsers/domparser.[h|cc], saxparser.[h|cc]: Added - parse_memory_raw() for libxml documents that are not utf8-encoded or - are encoded in an unknown encoding. - * examples/: Added dom_parser_raw() to test parsing of UCS2-encoded - text. - -2004-12-20 Murray Cumming - - * This is the HEAD branch, for gnome 2.9/2.10. - -2004-12-18 Murray Cumming - - * libxml++/docs/index.html: Bugs: Minor english corrections, and - more useful bugzilla links. - * libxml++/docs/Makefile.am: Build the reference documentation as - part of the main cvs build, but distribute it so that it does not need - to be rebuilt when building a tarball. - -2004-12-18 Murray Cumming - - * libxml++/nodes/node.cc: Node::find(): Check the result of - xmlXPathEval and throw an exception about invalid xpaths, instead of - crashing. Bug #161549 from Caleb Epstein. - -2004-12-18 Murray Cumming - - * libxml++/parsers/saxparser.cc: parse_memory(), parse_chunk(), - domparser.cc: parse_memory, parse_chunk(): Use Glib::ustring::bytes() - to get the size of the array, not size() or length(), which gets - the number of utf8 characters. It might not even be utf8. - * examples/sax_parser_build_dom/svgparser.cc: Use !empty() instead of - size() > 0. It is more efficient. - -2004-11-30 Murray Cumming - - * libxml++/validator.h: Removed an extra ; that g++ 3.4 complains - about. - -2.8.0: - -2004-09-12 Murray Cumming - - * libxml++/libxml++.h: Add include for xmlreader.h. - * examples/saxparser/myparser.cc, saxparser_entities/myparser.cc: - Correct (and uncomment) the code to read the attribute values. - -2.7.1: - -2004-09-06 Christophe de Vienne - - * configure.in: Prepared release 2.7.1. - -2004-08-13 Christophe de Vienne - - * libxml++/parsers/domparser.cc, libxml++/parsers/parser.cc: Fixed - bug #150082. - -2.7.0: - -2004-06-24 Murray Cumming - - * configure.in, Makefile.am, libxml++-2.*.pc.in: Reverted the changes - that made it install a 2.8 pc.in file, and which decreased the .so - name. 2.8 is not parallel-installable with 2.6, and this would only - have been a half-done transition if it was. - -2004-06-22 Murray Cumming - - * libxml++/io/outputbuffer.cc, inputbuffer.cc: - Added include of libxml/globals.h before include of libxml/xmlIO.h, - because xmlIO.h needs the definition of - xmlParserInputBufferCreateFilenameFunc. - -2004-05-28 Christophe de Vienne - - * configure.in, examples/Makefile.am, examples/dtdvalidation/Makefile.am, - examples/dtdvalidation/example.dtd, examples/dtdvalidation/main.cc, - libxml++/Makefile.am, libxml++/dtd.[h|cc], libxml++/io/Makefile.am, - libxml++/io/istreamparserinputbuffer.[h|cc], - libxml++/io/parserinputbuffer.[h|cc], - libxml++/libxml++.h, libxml++/validators/Makefile.am, - libxml++/validators/dtdvalidator.[h|cc] - libxml++/validators/validator.[h|cc]: - Integrated dtdvalidator patch proposed by Guillaume Arreckx. - Modified a bit the patch: - - renamed *.cpp -> *.cc - - fixed a few comments which where copy/paste from other files - - replaced std::string with Glib::ustring - - Added Dtd::cobj, since the patch rely on it. - - added a validaty_error as suggested by jon - - -2004-04-26 Christophe de VIENNE - - * libxml++/nodes/contentnode.cc: Fixed set_content which used xmlNodeAddContent - instead of xmlNodeSetContent (thanks to Marcello Orizi who outlined it). - -2004-05-05 Christophe de Vienne - - * libxml++/parsers/saxparser.cc: One more (last one I hope) change - about Glib::ustring instanciation from a buffer + lenght. We now - use Glib::ustring::ustring(In begin, In end) constructor. Thanks to - Jonathan Wakely. - -2004-05-04 Christophe de Vienne - - * libxml++/parsers/saxparser.cc: Replaced again the use of - Glib::ustring(const char*) constructor by Glib::ustring(std::string). - Fixes #141824. - -2004-05-04 Christophe de Vienne - - * libxml++/parsers/saxparser.cc: Replace the use of - Glib::ustring(const char*, unsigned) constructor by Glib::ustring(const char*). - Fixes #141824. - -2004-05-04 Murray Cumming - - * libxml++-2.6.pc.in: Made it require glibmm-2.4, so that apps do not - have to check for this themselves. - -2.6.0: - -2004-04-13 Murray Cumming - - * libxml++/Makefile.am: Change library name to 2.6 instead of 2.5. - * libxml++-2.6.pc.in: Report the changed library name. - -2004-03-27 Murray Cumming - - * libxml++/parsers/textreader.[h|cc]: Correct constness of - get_current_node(), so there is a const and non-const version. - -2.5.2: - -2004-02-16 Christophe de VIENNE - - * libxml++/nodes/element.cc: Check return value of xmlHasNsProp to - fix issue #134390 (as reported by John Coyle). Use xmlHasProp instead - of testing each attributes. - -2004-02-16 Christophe de VIENNE - - * libxml++-2.6.pc.in: Added libxml-2.0 to Requires: and removed - @LIBXML_LIBS@ from libs, as suggested by Albert Chin. - -2004-02-16 Christophe de VIENNE - - * libxml++/nodes/node.cc, libxml++/parsers/parser.h: - Merged in patches from Albert Chin to get libxml++ build using the SUN, - HP, SGI & AIX C++ compilers. - -2004-02-13 Jim Garrison - - * libxml++/attribute.h, libxml++/document.h, libxml++/dtd.h, - libxml++/io/ostreamoutputbuffer.[h|cc], - libxml++/io/outputbuffer.[h|cc], libxml++/keepblanks.[h|cc], - libxml++/nodes/node.h, libxml++/parsers/parser.h, - libxml++/parsers/saxparser.h, libxml++/parsers/textreader.[h|cc]: - Removed unnecessary semicolons - -2.5.1: - -2004-02-08 Jim Garrison - - * libxml++/document.[h|cc]: added Document::cobj() function - -2004-02-06 Christophe de Vienne - - * libxml++/parsers/sax_parser.cc: Fixed issue #132014. - -2004-02-06 Christophe de Vienne - - * libxml++/parsers/[Makefile.am|textreader.h|textreader.cc]: Added - TextReader interface. It is almost the patch which is here : - http://sourceforge.net/tracker/index.php?func=detail&aid=842730&group_id=12999&atid=312999 - with Glib::ustring instead of std::string, and member functions names - changed to be consistent with other interfaces. - * configure.in, examples/Makefile.am, examples/textreader: Added an example - of TextReader interface. - -2004-02-05 Jim Garrison - - * libxml++/document.[h|cc]: added create_root_node_by_import() - -2004-01-13 Christophe de Vienne - - * libxml++/io/document.cc: Gives NULL strings instead of empty ones to - xmlCreateIntSubset. Fixes issue #131329. - -2004-01-12 Christophe de Vienne - - * libxml++/io/outputbuffer.cc: Fix return value of xmlIO callbacks. (Fixes - issue #131018). - -2003-12-19 Murray Cumming - - * configure.in: Added glibmm-2.4 to the pkg-config check. - * Used regexxer to do a complete std::string/Glib::ustring rename. - Everything seems to still work. I think the parse_chunk(stream) - stuff might need some attention/thought. - -2003-12-19 Murray Cumming - - * removed acinclude.m4 because we do not need it anymore because - we do not need AM_LIBXML now that we use pkg-config. - * libxml++/Makefile.am: Generate a library with 2.5 in the name, - instead of 1.0 - * configure.in: Change version to 2.5.0. - * examples/Makefile.am_fragment: Link to the new library name. - * Renamed libxml++-1.0.pc.in to libxml++-2.6.pc.in: and changed the - library name that pkg-config reports for --libs. - * So, this is now the libxml++ 2.6 API, with a library name of 2.5 - while it is unstable. It is parallel-installable with libxml++ 1.0. - -This is the HEAD branch, for libxml++ 2.5/2.6. - -1.0.0: - -2003-12-18 Ephraim Vider - * examples/sax_parser_build_dom/svgelement.cc,svgpath.h: - - removed unneeded method qualification (msvc6 error) - * examples/sax_parser_entities/myparser.cc: - - removed namespace qualification (msvc6 error) - - removed return from void function - -2003-12-18 Ephraim Vider - - * win32_msvc6: updated MSVC projects to include new sources and examples - -2003-12-12 Christophe de Vienne - - * libxml++/parsers/sax_parser.cc: removed initialisation of userData - with this at the context creation (solution given by Murray). - -2003-12-11 Murray Cumming - - * libxml++/Makefile.am: Generate a library with 1.0 in the name, - instead of 0.1 - * configure.in: Change version to 1.0.0, and change shared library - version to 1.0.0 because we are staring again witt the first - version of a new shared library. - * examples/Makefile.am_fragment: Link to the new library name. - * libxml++-1.0.pc.in: Change the library name that pkg-config - reports for --libs. - -2003-12-08 Ephraim Vider - - * libxml++/document.cc: remove return statement from void functions - -0.28: - -2003-12-08 Christophe de Vienne - - * libxml++.spec.in: Removed libxml++.m4 and xml++-config from %files - section. - -2003-12-08 Murray Cumming - - * examples/ Added sax_parser_build_dom example from Dan Dennedy. - It does some funky stuff (see the comments) but it is an - interesting concept. See the description in examples/README. - -2003-12-03 Christophe de Vienne - - * configure.in: use libxml-2.0 instead of xml2 for libxml2 detection - by pkg-config. - * libxml++/parser/sax_parser.[h|cc]: Replaced AttributeMap by AttributeList, - which is now an ordered container (std::deque). Added a functor that can be - used with std::find_if to get an Attribute by it's name. - * libxml++/document.h: Fixed a typo in a doxygen command. - -2003-12-03 Murray Cumming - - * examples/README: explained what the examples do. - -2003-11-28 Christophe de Vienne - - * libxml++/docs/index.html: Added libxml2 version we relay on, as - suggested by Paul Breslin. - * configure.in: Prepared 0.28 release. Check for libxml2 >= 2.5.8 using - pkg-config instead of old-style autoconf macro. - * acinclude.m4: Removed. - -2003-11-27 Murray Cumming - - * Added examples/sax_parser_entites to test the new functionality. - * Added doxygen documentation to almost every class and method, - including mentioning that the parse methods throw exceptions. - -2003-11-27 Murray Cumming - - * Applied patch from Dan Dennedy to add entity handling to the - SAX parser, using a 2nd Document instance to manage the entity - definitions in order to provide a default entity reference resolver - implementation for on_get_entity(). With some minor changes from me. - -2003-11-13 Christophe de Vienne - - * libxml++/io/Makefile.am: Made libio a non installed library. - * libxml++/document.cc: Fixed a serious issue with threading: callbacks - were defined only for the main thread. - -0.27: - -2003-10-28 Murray Cumming - - * libxml++/nodes/element.[h|cc]: Changed get_child_content() to - get_child_text(), set_child_content() to set_child_text(), - add_comment() to add_child_comment(), and add_content() to - add_child_content() to make the API clearer. - -2003-10-25 Christophe de Vienne - - * libxml++/document.[h|cc]: Added Document::add_comment and added some - documentation. - -2003-10-22 Murray Cumming - - * libxml++/parsers/saxparser.[h.cc]: Added on_entity_declararation() - callback, and demonstrated it in examples/sax_parser/. - Added documentation to on_get_entity() giving clues about how to use - it, though it is too difficult for me to try. - -2003-10-18 Christophe de Vienne - - * All: All private members previously having a leading underscore in their - name now have it postfixed. Ex: _impl becomes impl_. - -2003-10-18 Christophe de Vienne - - * libxml++/io/outputbuffer.[h|cc]: Removed conversion operator to - underlying C structure. cobj() is now public. - * libxml++/document.cc: use OutputBuffer::cobj() instead of implicit - conversion. - -2003-10-18 Christophe de Vienne - - * libxml++/nodes/Makefile.am: Removed some trailing white spaces after a - backslash. - -2003-10-14 Murray Cumming - - * Added lots of doxygen documentation, try to document everything 100%. - * libxml++/nodes/element.[h|cc]: Made get_attributes() non-const - and added a const get_attributes() const overload, like - Node::get_children(). - * Moved AttributesList typedef from Node to Element, because that's - where it is used. - * libxml++/parsers/parser.[h|cc]: Added get/set_substitute_entities(), - like get/set_validate(), which affects _context->replaceEntities in - initialize_context(). - * Added libxml++/nodes/entityreference.[h|cc], with a - get_resolved_text() method. - * libxml++/document.cc: - - on_libxml_construct(): For the default, used when a node is not - recognised, create a Node rather than a ContentNode. Everything is a - Node so this should have less chance of being wrong. - - Added case to create an EntityReference. - * Added examples/dom_parse_entities. - -2003-09-30 Jonathan Wakely - - * libxml++/document.cc, libxml++/nodes/element.cc, - libxml++/nodes/node.cc: Preserve const-quals when casting between - strings of different character types. - -2003-09-26 Christophe de Vienne - - * libxml++/io/outputbuffer.[h|cc]: Yet another cleaning of the interface - and implementation. OutputBuffer is now non copyable, and the callback - process is now the same for write and close. - * libxml++/io/(ostream)outputbuffer.h: Added Doxygen documentation. - -2003-09-26 Christophe de Vienne - - * libxml++/io/: Small corrections after Murray comments on the patch. It's - even more clean now. - -2003-09-26 Christophe de Vienne - - * libxml++/io/: Added classes to wrap xmlIO output buffers. This classes - are OutputBuffer and OStreamOutputBuffer. - * libxml++/document.h: - - Added write_to_stream, which is implemented thanks to OutputBuffer. - - Removed virtual specifier on write_to_xxx functions. Their - implemention now calls a private virtual function do_write_to_xxx. This - also avoid having almost identical functions implementation in normal and - formatted versions of the functions. - -2003-09-24 Christophe de Vienne - - * libxml++/examples/dom_build/main.cc: Now demonstrate add_comment - too. - -2003-09-24 Dan Dennedy - - * libxml++/nodes/element.[h|cc]: Added Element::add_comment. - -2003-09-23 Christophe de Vienne - - * libxml++/document.h, libxml++/keepblanks.h, libxml++/noncopyable.h, - libxml++/nodes/node.h: Updated documentation. - -0.26: - -2003-09-22 Christophe de Vienne - - * examples/dom_build/main.cpp: Use Element::set_attribute instead of - Element::add_attribute which no longer exists. - -2003-09-19 Murray Cumming - - * libxml++/node/element.h: Removed add_attribute because it is the same as - set_attribute. - -2003-09-18 Murray Cumming - - * libxml++/node/element.h: Added set_namespace_declaration(). - element, node: methods take prefix instead of uri and prefix, because - that's what we want to specify most of the time. If no such namespace - prefix has been declared then an exception will be thrown. If we want - to specify a node name and attribute namespaces by uri (which would - result in a prefix in the eventual .xml code) then we could add those - methods later. If anybody needs them. - -2003-09-17 Christophe de Vienne - - * docs/reference/Doxyfile(.in): Doxyfile is now generated from Doxyfile.in - by configure so the version number is included in main page. The dot image - format is changed to png, the index is not disabled anymore. - -2003-09-15 Fredrik Arnerup - - * libxml++/document.cc: Added a call to xmlInitParser to avoid - threading problems. - -2003-09-05 Murray Cumming - - Based on the patch from Dan Dennedy, with changes: - * libxml++/node.[h|cc], - libxml++/element.[h|cc]: Added namespace_uri and namespace_prefix - parameters to methods, to support speficiation of nodes and children - also with namespace information. - * Added Node::get_namespace_prefix() and get_namespace_uri() and - set_namespace(). - * examples/dom_build/: Modified the example to do namespace stuff, - to test this. - -2003-08-20 Murray Cumming - - * libxml++/node.[h|cc]: import_node() now takes a _const_ Node, as - suggested by Rafael Vuijk. - -2003-07-20 Ephraim Vider - - * win32_msvc6: libxml++.dsp, examples/import_node.dsp, examples/Makefile.am: - - added import_node example project - -0.25: - -2003-07-16 Christophe de Vienne - - * libxml++.m4, xml++-config.in, configure.in, Makefile.am: removed old-style - autoconf libxml++ detection macro and script. - -2003-07-15 Christophe de Vienne - - * all but exceptions/*.[h|cc]: removed throw specification from functions - declaration. - -2003-07-11 Eric Bourque - - * nodes/node.[h|cc]: Added import_node function - * examples/import_node: Added an example of using import_node, and modified - autoconf files accordingly. - -2003-06-25 Ephraim Vider - - * win32_msvc6: libxml++.dsp: added _REENTRANT to support libxml with threads - - examples/Makefile.am: added new example project - -2003-06-16 Christophe de Vienne - - * docs/index.html: Added a link to Doxygen website. - -2003-06-16 Ephraim Vider - - * win32_msvc6/*: Fixed MSVC6 project files. - -2003-06-13 Christophe de Vienne - - * docs/Makefile.am: Fixed the post-html rule which was sending twice the - reference. - * docs/index.html: Added keyword "XML". - -0.24: - -2003-06-11 Christophe de Vienne - - * libxml++/parsers/domparser.cc: - - Fixed parse_stream. Parsing success was not checked before creating - Document. - - Check for errNo after parsing. - -2003-06-02 Ephraim Vider - * libxml++/nodes: - Added ContentNode as a base class for all non-element nodes - - TextNode and CommentNode are derived from ContentNode - - Added CdataNode and ProcessingInstructionNode as specific types - derived from ContentNode - - Will create ContentNode as a default node type when assert is - disabled - - Modified dom_parser example to better handle new types - Modified files: textnode.[h|cc] commentnode.[h|cc] - Added files: contentnode.[h|cc] cdatanode.[h|cc] processinginstructionnode.[h|cc] - - * node.cc: - Fix. return empty string and not 0 - * updated MSVC projects to include new sources and example - -2003-06-10 Jonathan Wakely - - * libxml++/parsers/saxparser.cc: Replace with - to support older compilers. - -2003-06-06 Christophe de Vienne - - * libxml++/document.cc: Little change in write_to_xxx_formatted. The - keepblanks parameter is kept to true, but xmlIndentOutputTree is set to 1. - This avoid libxml2 to add some significant whitespace into content nodes, - but still format the output. - -2003-06-05 Christophe de Vienne - - * libxml++/keepblanks.[h|cc]: Moved KeepBlanks::Default definition - to .cc file if compiler is MSVC 6.0. - -2003-06-04 Morten Hanssen - - * libxml++/Document.cc: Fixed a memory leak in - write_to_string[_formatted]() functions. - -2003-06-02 Murray Cumming - - * libxml++/Document.[h|cc]: Removed the standalone parse_* methods - because they just duplicate functionality and nobody seems to be - using them. - Renamed the private construct() and destruct() callbacks to - on_libxml_construct() and on_libxml_destruct() and added some - simple comments to explain their purpose. - * libxml++/node.[h|cc]: Added Node::is_white_space(), to make it - easier for the application to ignore white space. Used it in - the dom_parser example.. - -2003-05-29 Murray Cumming - - * Removed some struct keywords from method and variable definitions. - They don't seem to be necessary, and they do not match the method - definitions in the .cc files. - * Some syntax clean-up - tabs to spaces and adding spaces. - * examples/dom_parse/main.cc: Say when something is a text node. - -2003-05-28 Christophe de Vienne - - * lixml++/document.[h|cc]: Added write_to_file_formatted and - write_to_string_formatted. - -2003-05-25 Jonathan Wakely - - * libxml++/parsers/saxparser.cc: Included - -2003-05-23 Jonathan Wakely - - * libxml++/parsers/saxparser.[h|cc]: Correct comments. - -2003-05-23 Christophe de Vienne - - * all header files: Removed libxml2 headers inclusion. Added necessary - forward declaration of libxml2 structures. - * libxml++/parsers/saxparser.[h|cc]: Moved static callback functions into - a struct defined only in the .cc file, SaxParserCallback. - Added boolean parameter to SaxParser constructor to activate on_get_entity - callback (default to false). This technique could eventually be extended to - other functions in the future. - * libxml++-1.0.pc.in: removed libxml headers include path from Cflags. - -2003-05-22 Christophe de Vienne - - * libxml++/nodes/node.[h|cc]: Added Node::set_name(). - -2003-05-20 Christophe de Vienne - - * libxml++/nodes/[node.cc|element.h]: Minor syntax adjustments to allow - compiling with g++ -ansi -pedantic -Wall without any warning. - -0.23: - -2003-05-20 Christophe de Vienne - - * libxml++/keepblanks.[h|cc]: New KeepBlanks class which change settings - related to xmlKeepBlanksDefault and xmlIndentTreeOuput. - * libxml++/[document.cc|parsers/*parsers.cc]: use KeepBlanks instead of - manually call xmlKeepBlanksDefault(). Significant white spaces are not - removed/added anymore. - * example/dom_read_write/example_output.xml: removed. - -2003-05-16 Murray Cumming - - * libxml++/noncopyable.[h|cc]: New xmlpp::NonCopyable base class, which - should prevent people from using automatically-generated copy - constructors when they shouldn't. Not tested yet. - * libxml++/examples/dom_read_write: New example/test. This does - show that we are removing significant white space. This has been - discussed on the list and apparently Christophe has a fix for it. - -2003-05-06 Andy Glew - - * libxml++/nodes/node.cc: Node::find( nonexistent_xpath ) now return - empty NodeSet - -2003-04-24 Christophe de Vienne - - * libxml++/parsers/saxparser.cc: Fixed a memory leak pointed by "thierry" - . The sax handler of the context is not reset - to 0 before context release anymore. In parse() the default one is saved - then restored after effective parsing, so libxml handle itself its - destruction. - -2003-04-20 Christophe de Vienne - - * libxml++/document.cc: Removed a warning message that was put on std::cout - if an unknown type of node was created and replaced it by an assert. This - avoid the need to include iostream(.h). - -2003-04-18 Murray Cumming - - * Applied Jaka Jejcic's patch to fix compilation on NetBSD, including - iostream.h instead of istream.h. - -2003-04-09 Eric Bourque - - * libxml++.spec.in: modified spec file to be library version agnostic. - -2003-03-19 Ephraim Vider - - * added msvc support in win32_msvc6. - -2003-03-17 Ephraim Vider - - * Modified sax_exception example: - - corrected Clone() return type for MyException in myparser.[h|cc] - - catch all exceptions in main.cc - handle real errors too - -0.22: - -2003-03-15 Murray Cumming - - * libxml++/parser/domparser.cc: Added const overload of get_document(). - -2003-03-13 Christophe de Vienne - - * libxml++/parser/domparser.cc: Test if context creation is - successfull in the different parse_xxx functions. If it is no an - internal_error is thrown. - -2003-03-06 Ephraim Vider - - * made DomParser a wrapper around Document - removed all functions that were duplicates of document - functions and added get_document() - files: domparser.[h|cc] document.h - - * fixed compilation errors for msvc: - - corrected Clone() return type for derived exceptions - - corrected getline to std::getline in saxparser.cc - - changed clear() to erase() in parser.cc - - added #define for vsprintf in parser.h - - fixed warning in element.cc - -0.21: - -2003-02-21 Eric Bourque - - * Added spec.in, for creating RPMs. - -2003-02-20 Murray Cumming - - * libxml++/nodes/node.[h|cc]: Moved get_child_content(), - set_child_content(), add_content(), and has_content() from Node to - derived Element class instead of just throwing an exception if it - isn't an Element. This means you can't use set_child_content() on a - TextNode - you should be using TextNode::set_content() anyway, which - makes a lot more sense. Corrected set_child_content() to create a - TextNode instead of creating a node with the content as the name, - fixing the output of the dom_build example. - -2003-02-20 Murray Cumming - - * libxml++/parsers/parser.[h|cc]: - initialize_contex(): Request iniitialization and connect callbacks - check_exception(): Throw exception if any validation problems have - been found - the messages are built up gradually by repeated - callbacks. - set_validate(): Enables validation before calling parse_*(). - Alternatively, use 2nd bool parameter to the DomParser constructor. - * libxml++/exceptions/: Added validation_error class. - * examples/dom_parser: Added a DTD and changed example.xml to - something that uses it. Also added example_invalid.xml to test - the exceptions. - -2003-02-12 Ole Laursen - - * examples/sax_parser/main.cc: Added chunk-wise parsing to the - example. - - * libxml++/parsers/saxparser.[h,cc]: Added functionality for - parsing chunks of data. - -2003-02-17 Murray Cumming - - * libxml++/parsers/*.[h|cc]: All parsing is now done via contexts, - which required a little duplication of the implementation of functions - such as xmlParseFile(), most of which is now in - DomParser::parse_context(). This avoids use of global functions such - as xmlKeepBlanksDefault() by setting these booleans directly in the - context, in Parser::initialize_context(). - However, xmlCreateFileParserCtxt() does seem to be affected by - xmlKeepBlanksDefault so we still have to use it temporarily, restoring - the old value afterwards - see the comments in DomParser::parse_file(). - This should allow us to add validation to the API. - -0.20: - -2003-02-15 Murray Cumming - - * libxml++/nodes/node.cc: (remove_child): Implemented it with - xmlUnlinkNode and xmlFreeNode, so that it's actually removed. - -2003-02-15 Murray Cumming - - * Added examples/dom_xpath, with code from Stefan Seefeld's dom - example. - -2003-02-15 Murray Cumming - - * Reverted the Node::child_iterator API change because it was - undiscussed and is unfinished. The BRANCH_1_0 and HEAD branches are now - merged. BRANCH_1_0 should no longer be used. This was never in 0.19. - -0.19: - -2003-02-07 Murray Cumming - - * Moved method implementations such as get_attributes() into derived - classes instead of using "using methodname();". That seems clearer. - However it shows that we should probably create a shared base class for - Content and Comment, as in the DOM. - -2003-02-06 Murray Cumming - - * libxml++/parsers/saxparser.[h|cc]: Corrected some coding style. - -2003-02-06 Murray Cumming - - * Changed c_obj() to cobj() because it's more like gobj() used in - gtkmm, gnomemm, etc. - -2003-02-06 Murray Cumming - - * libxml++/nodes/node.*: Corrected code style. - -2003-02-06 Murray Cumming - - * libxml++/nodes/node.[h|cc], libxml++/attribute.[h|cc]: Made c_obj() - accessors public so people can use them. Provided const and non-const - versions of them. Put implementation in .cc file. - * Reverted some of Stefan's coding style changes and corrected the - coding style in libxml++/nodes/document.[h|cc]. - * libxml++/document.h: Made the destructor virtual, because there are - virtual methods. - -2002-02-04 Stefan Seefeld - - * libxml++/node.[h,cc]: add new insert_child and append_child methods - (using new iterators), add get_path and find methods for xpath lookup - - * examples/dom: new example code to illustrate the new features - -2002-02-03 Stefan Seefeld - - * libxml++/node.h, libxml++/parsers/saxparser.[h,cc], - examples/sax_parser/*.[h,cc], examples/sax_exception/*.[h,cc]: - SaxParser::AttributeMap is now a map. - -2002-02-03 Stefan Seefeld - - * libxml++/node.h: add child_iterators for simple C++ style - iteration (to get eventually rid of NodeList) - -2002-02-03 Stefan Seefeld - - * libxml++/attribute.[h,cc], libxml++/nodes/node.[h,cc], - libxml++/document.cc: derive Attribute from Node, and make - get_value() use libxml2 accessor instead of raw pointer - -2002-02-03 Stefan Seefeld - - * libxml++/document.[h,cc], libxml++/parsers/domparser.[h,cc], - libxml++/libxml++.h, libxml++/Makefile.am: introduce new Document type. - * examples/dom_build/main.cc: make dom_build example use new - Document type - -2002-02-03 Stefan Seefeld - - * acinclude.m4: The AM_LIBXML macro now checks for a libxml2 - version >= 2.5.1. - * libxml++/nodes/node.cc: compare strings, not pointers, in - get_attribute() - -2003-01-31 Stefan Seefeld - - * various: overall change to use libxml2 as implementation, - not only as I/O backend. With corrections by Murray Cumming. - Further explanation by murrayc: Instead of maintaining its own - C++ data structures and then creating libxml data structures from them, - it now manipulates the libxml data structures directly, so the C++ and C - APIs are always in sync. - -2003-01-21 Valentin Rusu - - * added CDATA section handler to SaxParser - -2003-01-05 Valentin Rusu - - * fixed a potential buffer overflow problem into saxparser.cc - -0.18: - -2003-01-31 Stefan Seefeld - - * various: overall change to use libxml2 as implementation, - not only as I/O backend. - -2003-01-05 Murray Cumming - - * examples/dom_build/main.cc: Removed some useless test C code. - -2002-12-24 Morten Brix Pedersen - - * Include instead of to compile on gcc 2.95.4. - -2002-12-26 Murray Cumming - - * libxml++/nodes/element.c (write): Add back the code to write the - attributes to the C libxml structure. This code got lost during the - refactoring. - -2002-12-25 Murray Cumming - - * Removed unused constructors, to simplify things. Made Node's - destructor virtual, because we delete them polymorphically, and - because it has virtual methods. - -2002-12-25 Murray Cumming - - * libxml++/nodes/node.[h|cc]: Removed the initialized member - variable and its accessor, because it's not used. - -2002-12-19 Murray Cumming - - * libxml++/parsers/domparser.[h|cc]: get/set_root_node() now returns - an Element instead of a Node. - -2002-12-19 Murray Cumming - - * Changed const & accessors to get_*() methods. For instance, - Node::name -> Node::get_name - Node::children() -> Node::get_children() - Element::attributes() -> Element::get_attributes() - Attribute::value -> Attribute::get_value() - -2002-12-18 Murray Cumming - - * Added libxml++/nodes/commentnode.[h|cc] and used it in Node so that - comments don't just show up as name=comment Nodes. - * examples/dom_parser/example.xml: Added a comment. - * examples/dom_parser/main.cc: Do a dynamic_cast<> check for comments - too. - -2002-12-18 Christophe de Vienne - - * libxml++/parser/saxparser.cc: Fixed a bug in exception handling in - parse_stream. Thanks to Fredrik Arnerup for reporting - the bug. - -2002-12-17 Murray Cumming - - * Added libxml++/nodes/textnode.[h|cc]. This should remove the - confusion about whether content()/set_content() should be used on - a text node or the parent of a text node. - * libxml++/nodes/node.[h|cc]: - - Node::write() is now virtual, and - different in TextNode. - - content() replaced by get_child_content, which returns a TextNode* - instead of a string. - - set_content() replaced by set_child_content(). - * Added libxml++/nodes/element.[h|cc] so that TextNode can inherit - from a Node class without the attributes API. As per the Java DOM API, - Node still has the children API - I guess there's some reason for that, - though I don't see how a TextNode could have children. - -2002-12-17 Murray Cumming - - * Moved node.[h|cc] into nodes sub directory, in preparation for the - multiple-node-types API change. - -2002-12-12 Jonathan Wakely - - * libxml++/parsers/saxparser.cc, saxparser.h (on_get_entity): New - virtual function to allow derived classes to override entity handling - -2002-12-16 Murray Cumming - - * libxml++/node.cc: write(): - - Don't set the node->type directly. Let - xmlNodeSetContent take care of adding a suitable child node. This - was leading to segfaults when write() later tried to add a child node - to a text node. - - Throw internal_error exception when xmlNewChild returns NULL. - - -0.17:. - -2002-12-10 Christophe de Vienne - - * configure.in: updated version numbers for next release. Generic - version is now 0.17, library version is 3:0:0 - * NEWS: updated with changes since 0.16 version. - -2002-12-10 Christophe de Vienne - - * libxml++/node.cc: fixed write() which was using the accessors content() - and has_content(). Since they return something for both the text - node and the parent node, the output was weird. - -2002-12-09 Murray Cumming - - * libxml++/node.cc: content(): If the cached content string is empty, - try to get the content of a child "text" node. This makes content() - work as expected after creating a document with set_content() and - later reparsing it. - -2002-12-09 Murray Cumming - - * libxml++/parsers/dom_parser.cc (release_underlying): Set pointers - to 0 so that the get_*() methods generate new instances instead of - returning invalid pointers. - -2002-12-09 Murray Cumming - - * libxml++/node.cc: Node::remove_child() and Node::remove_attribute: - delete the objects when forgetting about them. - * libxml++/node.h: Added reference docs explaining the above. - -2002-12-07 Murray Cumming - - * libxml++/parsers/domparser.cc, saxparser.cc: Added comments about - the use of xmlKeepBlanksDefault() and xmlLineNumbersDefault(). - * libxml++/parsers/saxparser.[h|cc]: Change exception & to exception&. - -2002-12-06 Christophe de Vienne - - * libxml++/parsers/domparser.cc: Enabled xml option LineNumbers - and disabled KeepBlanks before each parsing. - * libxml++/parsers/sax_parser.cc: Enabled xml option KeepBlanks - before each parsing. - * example/dom_parser/main.cc: Added line number display for each - non-content node. Changed a bit content display - * Note: in a near future I may change these options settings to - let the user choose which options he wants/wants not. - - -2002-12-03 Jone Marius Vignes - - * libxml++/parsers/domparser.cc: Changed the exception in - write_to_string() to "write_to_string() failed." - * libxml++/parsers/domparser.h: Corrected documentation of - write_to_string() and write_to_file() to clarify that these methods - doesn't return booleans - -2002-12-02 Christophe de Vienne - - * libxml++/exceptions/*.[h|cc]: Added and implemented virtual - methods Raise() and Clone. - * libxml++/parser/sax_parser.[h|cc]: Each callback method can now - throw some exceptions as long as they herit from xmlpp::exception - AND implement Raise() and Clone(). - * libxml++/examples/sax_exception/: Added an example which demonstrate - the use of exceptions inside a SaxParser. - -2002-11-29 Murray Cumming - - * autogen.sh: Added libtoolize to generate files such as ltmain.sh. - -2002-11-28 Christophe de Vienne - - * acinclude.m4: The AM_LIBXML macro now checks for a libxml2 - version >= 2.4.1. - -2002-11-21 Christophe de Vienne - - * libxml++/parsers/*.[h|cc]: added Parser::parse_stream method - and implemented it in both DomParser and SaxParser. Tests based - on the examples (not commited in the cvs) worked perfectly. - -2002-11-20 Christophe de Vienne - - * libxml++/parsers/saxparser.cc: fixed a memory leak (thanks - to Chris Leishman who reported it. - -2002-11-20 Murray Cumming - - * Changed use of the term properties to attributes in the API, - because that is the correct terminology. - -0.16: - -2002-11-19 Christophe de Vienne - - * configure.in: updated version numbers for next release. - version is set to 0.16, library version to 2:0:0 - -2002-11-19 Murray Cumming - - * docs: Added index.html, which can be a main website page. - * docs/Makefile.am: Added rsync command to upload the html, - including the reference documentation. - -2002-11-19 Murray Cumming - - * Added Dtd class, which is just a collection of std::strings. - * libxml++/parsers/domparser.[h|cc]: Added set_internal_subset() and - get_internal_subset() to set the DTD declaration. This is set in the - underlying C xmlDoc during write_to_file() and write_to_disk(). - -2002-11-18 Murray Cumming - - * libxml++/node.[h|cc]: - - Rename is_content() to has_content(), because that's what it tells - us. Removed _is_content member bool - we can check _content.empty() - instead. - - write(): Do not manually set the xmlNode's type field to TEXT. This - corrupted the tree. Tested content nodes in example/dom_build. - -2002-11-18 Murray Cumming - - * libxml++/parsers/domparser.cc (write_to_*): Corrected no-root-node - check. - -2002-11-18 Murray Cumming - - * libxml++/exceptions/exception.[h|cc]: Corrected signature of what() - method, adding const throw(). - -2002-11-18 Murray Cumming - - * libxml++/parsers/domparser.[h|cc]: Added DomParser::set_root_node(). - * examples: Added dom_build, to show runtime construction of an XML - tree. - -2002-11-18 Murray Cumming - - * Parser, DomParser, SaxParser: parse_file() and parse_memory() now - throw exceptions. - * DomParser::write_to_file(): throws exception instead of using a bool - return value. - * examples/domparser/: Catches exceptions. - -2002-11-18 Christophe de Vienne - * libxml++/exceptions: splitted exception.[h|cc] in this directory. - The libxml_error has been removed for now, and a parse_error added. - -2002-11-17 Christophe de Vienne - * libxml++/attribute.h: Changed macro __LIBXMLPP_PROPERTY_H to __LIBXMLPP_ATTRIBUTE_H - * libxml++/exception.[h|cc]: Added xmlpp::exception, xmlpp::libxml_error and - xmlpp::internal_error classes. It's very basic for now. - -2002-11-17 Murray Cumming - - * Node, Attribute: set_*() method now have void return types. - * DomParser: Now has an empty underlying in-memory document when the - default constructor is used. This means that get_root_node() should - always return something, so we can build XML documents in memory - without loading any XML first. - -2002-11-16 Murray Cumming - - * libxml++/attribute.h: Added explicit to constructor. - -2002-11-16 Murray CUmming - - * libxml++/parsers/domparser: Renamed write() method to write_to_file() - and added write_to_string(). - -2002-11-16 Murray Cumming - - * libxml++-1.0.pc.in: More corrections. This was hopelessly broken - before. - -2002-11-16 Murray Cumming - - * libxml++-1.0.pc.in: Corrected typo. - -2002-11-16 Murray Cumming - - * docs/reference/Doxyfile: Used doxywizard to mark the Recursive - option, so it reads the libxml++/parsers directory too. - -2002-11-16 Murray Cumming - - * Attribute, Node: Added Doxygen class comment block. Changed some - something * to something*. - -2002-11-16 Murray Cumming - - * libxml++/node.[h|cc]: Added parameter names. Made const and non-const - overloads of children() method. - * libxml++/parsers/domparser.[h|cc]: Added const get_root_node() const - overload. - -2002-11-16 Christophe de Vienne - * libxml++/parsers/*: renamed method Parser::parse to - Parser::parse_file - -2002-11-16 Christophe de Vienne - * libxml++/parsers/saxparser.[h|cc]: rewritten - SaxParser::parse(filename) and SaxParser::parse_memory(string). - They both use a SaxParser::parse() - method. The parse_chunk and finish methods has been removed. - * example/sax_parser/parser.cc: minor bugfix: the Attribute pointer - was printed instead of the value. - -2002-11-16 Christophe de Vienne - * Property: has been renamed to Attribute. However, the "properties" - token has been kept when speaking of all the attributes of a node, - as in the libxml library. - * node.cc: rewritten a few loops so they have a more 'c++' looking. - rewritten some portions of code where an attribute is searched by name. - -2002-11-15 Murray Cumming - * Changed e.g. std::string &something to std::string& something, - using regexxer. - -2002-11-15 Christophe de Vienne - * example/sax_parser/parser.cc: #included - -2002-11-15 Christophe de Vienne - * libxml++/parsers/saxparser.cc: #included cstdarg instead of stdarg.h - to follow the c++ standard. #included to have std::cerr - it's - needed on strict c++ compiler (g++ 3.2 for instance). - * example/dom_parser/main.cc: #included - -2002-11-15 Murray Cumming - - * libxml++/parsers/saxparser.cc: #included stdarg.h - it seems to - be necessary with some compilers. - -2002-11-15 Murray Cumming - - * DomParser:: Added get_encoding() and write() methods. - * Removed Tree - Use DomParser instead. - -2002-11-15 Murray Cumming - - * SaxParser now inherits from Parser, with parse() and parse_memory() - methods. - * Added example/sax_parser example, but the start_element callback - doesn't seem to be called. - -2002-11-15 Murray Cumming - - * Parser, DomParser: Added parse_memory() method. - * Node::children(): Removed bad early-optimisation hack - it returned - a static function variable instead of returning by value. This meant - that >1 results of children() could not be used simultaneously. - For instance, this meant that it could not be called recursively. - -2002-11-12 Murray Cumming - - * Node, Property: Used explicit keyword on constructors. - -2002-11-12 Murray Cumming - - * Added parsers directory. - * Renamed Parser to SaxParser. - * Added DomParser, intended as a replacement for Tree, but that has - not yet been removed. I don't intend to implement the libxml-1 - compatibility stuff. - * Added examples directory structure, with one tiny dom_parser example. - -2002-11-12 Christophe de Vienne - * node.[h|cc]: name() method now return a reference. - * Tree/Node: The readnode and writenode functions have been removed - and transfered somehow into Node as a new constructor and write(). - The libxml++-private.[h|cc] has been removed. - -2002-11-12 Murray Cumming - - * Parser: It's no longer a templated type - to provide your own - callback implementations you can now just derive your own parser and - override the on_*() methods. - -2002-11-12 Murray Cumming - - * Moved implementation into the .cc files. - * Changed n, v and p parameter names to name, value and properties. - -2002-11-12 Murray Cumming - - * Split the single xml.[h|cc] files into node, property, tree and - parser files, with a libxml++.h header file that includes them all. - * Removed the XML prefixes from type names - we don't need it because - we use a namespace now. - * Placed typedefed lists and map inside their classes. For instance, - XMLNodeList is now xmlpp::Node::NodeList. - * Node::children(): Use !(n.empty()) instead of (n.length() == 0), for - perfomance. - * Tree: changed fn parameter names to filename. - -2002-11-12 Christophe de Vienne - * AUTHORS: Added Murray Cumming to the contributors - -2002-11-08 Christophe de Vienne - * libxml++/xml.cc: corrected _line initialisation in XMLNode::XMLNode(const XMLNode *from) - -2002-11-08 Christophe de Vienne - - * libxml++/xml.cc: Test if doc encoding is not null before - reading it (thanks to Marcel Bosc). - -2002-11-05 Murray Cumming - - * Added docs/reference/. Run make in this directory to generate - reference documentation with doxygen. - * libxml++/xml.h: Removed macros around namespace - all compilers - must now support namespaces. - * libxml++/xml.[h|cc]: Replaced (void) with () - it's not necessary - in C++. - -2002-11-05 Murray Cumming - - * libxml++/Makefile.am and configure.in: Implemented shared library - interface versioning. - -2002-11-05 Murray Cumming - - * Put source code in libxml++ directory, ready for it to be split up - into separate files. Client code should now include - libxml++/xml++.h rather than just xml++.h. - -2002-11-05 Murray Cumming - - * Headers are now installed in a versioned directory, to allow - coexistence with future major versions of libxml++. You may need to - remove the previously installed xml++.h file. - * Library name changed to libxml++-0.1, to be changed to libxml++-1.0 - when libxml++ stabilizes its API. This is also to allow future versions - to be parallel installed. - * Added pkg-config file as a simpler and more maintainable alternative - to the -config file and m4 script. - -Version 0.14 - * Ported to g++ 3.2. The code should now also compile on compilers which are a bit more strict about c++ than previous versions of g++ - * Added method XMLNode::line() wich returns the line number of a non content node in the source file. - * Added encoding file support through XMLTree::encoding() and XMLTree::set_encoding() methods - * Replacement of hash_map by map for node properties lists, since it has been reported to be faster, and to simplify porting to other plarfoms. - * libxml++ classes has been put in a separated namespace, libxmlpp. If you don't want namespace, just undefine the LIBXMLPP_USE_NAMESPACE - * encoding and compression settings are now loaded at parsing of file/buffer. - - -Version O.12 to 0.13 - No Changelog. - -Version O.11 - * Modified interface to allow for more complete coverage of possible uses of XML files. - -Version O.10 - * Added SAX parser. - -Version O.2 to 0.9 - No Changelog. - -Version O.1 - * Original release. diff --git a/MSVC_NMake/MSVC-Builds.md b/MSVC_NMake/MSVC-Builds.md new file mode 100644 index 00000000..16da33b8 --- /dev/null +++ b/MSVC_NMake/MSVC-Builds.md @@ -0,0 +1,84 @@ +Building libxml++ with Visual Studio 2017 or later +- + +* You will need Visual Studio 2017 (MSVC 15.7.x) or later, as `C++-17` is +required and only 15.7.x or later had adequate `C++-17` support. +* Install libxml2 from https://xmlsoft.org/, either via Windows binaries or +building from source, using NMake or CMake. It is strongly recommended, if +building libxml2 from source, that Visual Studio 2015 or later is used. +* Add libxml2's include path to `%INCLUDE%` and its library path to `%LIB%`, or +placing the dependencies like the following: +``` +$(some_dir_1)\include + | + --libxml2\libxml\*.h + | + --(headers of libraries libxml2 depends on, such as ZLib, liblzma...) + +$(some_dir_2)\lib + | + --libxml2.lib + | + --(.lib's of libraries that libxml2 depends on, such as ZLib, liblzma) +``` +* You need libxml2's DLL and all of its dependent DLLs in `%PATH%` if linking +against a DLL build of libxml2 in order to run the tests. + +* Notice that for the built DLL and .lib the Visual Studio version is no +longer `vc$(VSVER)0`, but is named like the following (Visual Studio version), +to follow what is done in other C++ libraries such as Boost (use +`-Dmsvc14x-parallel-installable=false` to the Meson options or pass +`USE_COMPAT_LIBS=1` in the NMake commandline to override, recommended only if +rebuilding items using libxml++ is inconvenient): + * NMake: + * 2017: `VSVER=15`, `xml++-vc141-5_0.[dll|pdb|lib]` + * 2019: `VSVER=16`, `xml++-vc142-5_0.[dll|pdb|lib]` + * 2022: `VSVER=17`, `xml++-vc143-5_0.[dll|pdb|lib]` + * Meson: + * 2017: `VSVER=15`, `xml++-vc141-5.0-1[dll|pdb]`, `xml++-vc141-5.0.lib` + * 2019: `VSVER=16`, `xml++-vc142-5.0-1[dll|pdb]`, `xml++-vc142-5.0.lib` + * 2022: `VSVER=17`, `xml++-vc143-5.0-1[dll|pdb]`, `xml++-vc143-5.0.lib` + + +### NMake Builds +* Note that `$(Platform)` refers to the following: + * `$(Platform)` + * AMD64/x86_64/x64: `x64` + * ARM64/aarch64: `arm64` + * x86/i686: `Win32` + +* Run the following: +``` +cd $(srcroot)\MSVC_NMake +# Run "nmake /f Makefile.vc" to see to see what options are supported by +# the NMake Makefiles +# INCLUDEDIR is by default $(PREFIX)\include, and LIBDIR is by default +# $(PREFIX)\lib. PREFIX is by default $(srcroot)\..\vs$(VSVER\$(Platform). +# $(some_dir_1) and $(some_dir_2) refer to the sample layout listed above. + +nmake /f Makefile.vc CFG=[debug|release] [PREFIX=...] [INCLUDEDIR=$(some_dir_1)\include] [LIBDIR=$(some_dir_2)\lib] +``` +* The following targets are supported (only DLL builds are supported out of the +box with the NMake Makefiles): + * `all`, `libxmlxx_examples` (or nothing passed in): The libxml++ library as +a DLL with the example programs + * `tests`: The libxml++ library as a DLL with the test programs + +### Meson builds +Please also see [README.md](../README.md) for further details. + +For Visual Studio builds, it is also recommended that CMake is installed and can +be found in `%PATH%`, so that it can help with finding an installed libxml2, or +build libxml2 alongside with libxml++ if it is not previously installed. If +libxml2 is installed, you will most probably need to add its include directory +to `%INCLUDE%` and its library path to `%LIB%`, as described earlier. + + +Cedric Gustin +01/26/2005 + +Armin Burgmeier +10/03/2010 + +Chun-wei Fan +06/12/2020, updated 07/05/2023 diff --git a/MSVC_NMake/Makefile.vc b/MSVC_NMake/Makefile.vc new file mode 100644 index 00000000..bed3c95e --- /dev/null +++ b/MSVC_NMake/Makefile.vc @@ -0,0 +1,62 @@ +# NMake Makefile for building libxml++ on Windows using Visual Studio + +# The items below this line should not be changed, unless one is maintaining +# the NMake Makefiles. Customizations can be done in the following NMake Makefile +# portions (please see comments in the these files to see what can be customized): +# +# detectenv-msvc.mak +# config-msvc.mak + +!include detectenv-msvc.mak + +# Include the Makefile portions with the source listings +!include ..\libxml++\filelist.am + +# Include the Makefile portion that enables features based on user input +!include config-msvc.mak + +!if "$(VALID_CFGSET)" == "TRUE" + +# We need Visual Studio 2015 or later +!if $(VSVER) < 14 +VALID_MSC = FALSE +!else +VALID_MSC = TRUE +!endif + +!if "$(VALID_MSC)" == "TRUE" + +all: $(LIBXMLXX_LIB) libxmlxx_examples all-build-info + +# Include the Makefile portion to convert the source and header lists +# into the lists we need for compilation +!include create-lists-msvc.mak + +!ifdef GENERATE_VERSIONED_FILES +!include pkg-ver.mak +DO_REAL_GEN = 1 +!endif + +tests: $(libxmlxx_tests) all-build-info + +libxmlxx_examples: $(libxmlxx_examples) + +# Include the build rules for sources, DLLs and executables +!include generate-msvc.mak +!include build-rules-msvc.mak + +!include install.mak + +!else # "$(VALID_MSC)" == "TRUE" +all: + @echo You need Visual Studio 2015 or later. + +!endif # "$(VALID_MSC)" == "TRUE" + +!else # "$(VALID_CFGSET)" == "TRUE" +all: help + @echo You need to specify a valid configuration, via + @echo CFG=release or CFG=debug +!endif # "$(VALID_CFGSET)" == "TRUE" + +!include info-msvc.mak diff --git a/MSVC_NMake/build-rules-msvc.mak b/MSVC_NMake/build-rules-msvc.mak new file mode 100644 index 00000000..0802403a --- /dev/null +++ b/MSVC_NMake/build-rules-msvc.mak @@ -0,0 +1,97 @@ +# NMake Makefile portion for compilation rules +# Items in here should not need to be edited unless +# one is maintaining the NMake build files. The format +# of NMake Makefiles here are different from the GNU +# Makefiles. Please see the comments about these formats. + +# Inference rules for compiling the .obj files. +# Used for libs and programs with more than a single source file. +# Format is as follows +# (all dirs must have a trailing '\'): +# +# {$(srcdir)}.$(srcext){$(destdir)}.obj:: +# $(CC)|$(CXX) $(cflags) /Fo$(destdir) /c @<< +# $< +# << + +{..\libxml++\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{..\libxml++\exceptions\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{..\libxml++\io\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{..\libxml++\nodes\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{..\libxml++\parsers\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{..\libxml++\validators\}.cc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.obj:: + @if not exist vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ md vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx + $(CXX) $(LIBXMLXX_CFLAGS) $(CFLAGS_NOGL) /Fovs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /Fdvs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\ /c @<< +$< +<< + +{.\libxml++\}.rc{vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\}.res: + @if not exist $(@D)\ md $(@D) + rc /fo$@ $< + +# Rules for building .lib files +$(LIBXMLXX_LIB): $(LIBXMLXX_DLL) + +# Rules for linking DLLs +# Format is as follows (the mt command is needed for MSVC 2005/2008 builds): +# $(dll_name_with_path): $(dependent_libs_files_objects_and_items) +# link /DLL [$(linker_flags)] [$(dependent_libs)] [/def:$(def_file_if_used)] [/implib:$(lib_name_if_needed)] -out:$@ @<< +# $(dependent_objects) +# << +# @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2 +$(LIBXMLXX_DLL): $(libxmlxx_OBJS) + link /DLL $(LDFLAGS_NOLTCG) $(LIBXML2_LIBS) /implib:$(LIBXMLXX_LIB) -out:$@ @<< +$(libxmlxx_OBJS) +<< + @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;2 + +# Rules for linking Executables +# Format is as follows (the mt command is needed for MSVC 2005/2008 builds): +# $(dll_name_with_path): $(dependent_libs_files_objects_and_items) +# link [$(linker_flags)] [$(dependent_libs)] -out:$@ @<< +# $(dependent_objects) +# << +# @-if exist $@.manifest mt /manifest $@.manifest /outputresource:$@;1 + +clean: + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.exe + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.dll + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.pdb + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.ilk + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.exp + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\*.lib + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-tests\*.obj + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-tests\*.pdb + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-examples\*.obj + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-examples\*.pdb + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\*.res + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\*.obj + @-del /f /q vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx\*.pdb + @-rd vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-tests + @-rd vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-examples + @-rd vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx diff --git a/MSVC_NMake/config-msvc.mak b/MSVC_NMake/config-msvc.mak new file mode 100644 index 00000000..03ac22c7 --- /dev/null +++ b/MSVC_NMake/config-msvc.mak @@ -0,0 +1,57 @@ +# NMake Makefile portion for enabling features for Windows builds + +# These are the base minimum libraries required for building glibmm. +!ifndef INCLUDEDIR +INCLUDEDIR = $(PREFIX)\include +!endif +!ifndef LIBDIR +LIBDIR = $(PREFIX)\lib +!endif + +BASE_INCLUDES = /I$(INCLUDEDIR) + +# Please do not change anything beneath this line unless maintaining the NMake Makefiles +LIBXMLXX_MAJOR_VERSION = 5 +LIBXMLXX_MINOR_VERSION = 0 + +!if "$(CFG)" == "debug" || "$(CFG)" == "Debug" +DEBUG_SUFFIX = -d +!else +DEBUG_SUFFIX = +!endif + +LIBXMLXX_BASE_CFLAGS = \ + /I.\libxml++ /I.. /EHsc \ + /wd4244 /wd4101 \ + /std:c++17 + +LIBXMLXX_EXTRA_INCLUDES = \ + /I$(INCLUDEDIR)\libxml2 \ + /I$(INCLUDEDIR) + +LIBXMLXX_CFLAGS = /DLIBXMLPP_BUILD $(LIBXMLXX_BASE_CFLAGS) $(LIBXMLXX_EXTRA_INCLUDES) +LIBXMLXX_EX_CFLAGS = $(LIBXMLXX_BASE_CFLAGS) $(LIBXMLXX_EXTRA_INCLUDES) + +# We build xml++-vc$(VSVER_LIB)-$(LIBXMLXX_MAJOR_VERSION)_$(LIBXMLXX_MINOR_VERSION).dll or +# xml++-vc$(VSVER_LIB)-d-$(LIBXMLXX_MAJOR_VERSION)_$(LIBXMLXX_MINOR_VERSION).dll at least + +!if "$(USE_COMPAT_LIBS)" != "" +VSVER_LIB = $(VSVER)0 +MSVC_VSVER_LIB = +!else +VSVER_LIB = $(PDBVER)$(VSVER_SUFFIX) +MSVC_VSVER_LIB = -vc$(VSVER_LIB) +!endif + +!ifdef USE_MESON_LIBS +LIBXMLXX_LIBNAME = xml++$(MSVC_VSVER_LIB)-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION) +LIBXMLXX_DLLNAME = $(LIBXMLXX_LIBNAME)-1 +!else +LIBXMLXX_LIBNAME = xml++-vc$(VSVER_LIB)$(DEBUG_SUFFIX)-$(LIBXMLXX_MAJOR_VERSION)_$(LIBXMLXX_MINOR_VERSION) +LIBXMLXX_DLLNAME = $(LIBXMLXX_LIBNAME) +!endif + +LIBXMLXX_DLL = vs$(VSVER)\$(CFG)\$(PLAT)\$(LIBXMLXX_DLLNAME).dll +LIBXMLXX_LIB = vs$(VSVER)\$(CFG)\$(PLAT)\$(LIBXMLXX_LIBNAME).lib + +LIBXML2_LIBS = libxml2.lib diff --git a/MSVC_NMake/create-lists-msvc.mak b/MSVC_NMake/create-lists-msvc.mak new file mode 100644 index 00000000..654a87f7 --- /dev/null +++ b/MSVC_NMake/create-lists-msvc.mak @@ -0,0 +1,80 @@ +# Convert the source listing to object (.obj) listing in +# another NMake Makefile module, include it, and clean it up. +# This is a "fact-of-life" regarding NMake Makefiles... +# This file does not need to be changed unless one is maintaining the NMake Makefiles + +# For those wanting to add things here: +# To add a list, do the following: +# # $(description_of_list) +# if [call create-lists.bat header $(makefile_snippet_file) $(variable_name)] +# endif +# +# if [call create-lists.bat file $(makefile_snippet_file) $(file_name)] +# endif +# +# if [call create-lists.bat footer $(makefile_snippet_file)] +# endif +# ... (repeat the if [call ...] lines in the above order if needed) +# !include $(makefile_snippet_file) +# +# (add the following after checking the entries in $(makefile_snippet_file) is correct) +# (the batch script appends to $(makefile_snippet_file), you will need to clear the file unless the following line is added) +#!if [del /f /q $(makefile_snippet_file)] +#!endif + +# In order to obtain the .obj filename that is needed for NMake Makefiles to build DLLs/static LIBs or EXEs, do the following +# instead when doing 'if [call create-lists.bat file $(makefile_snippet_file) $(file_name)]' +# (repeat if there are multiple $(srcext)'s in $(source_list), ignore any headers): +# !if [for %c in ($(source_list)) do @if "%~xc" == ".$(srcext)" @call create-lists.bat file $(makefile_snippet_file) $(intdir)\%~nc.obj] +# +# $(intdir)\%~nc.obj needs to correspond to the rules added in build-rules-msvc.mak +# %~xc gives the file extension of a given file, %c in this case, so if %c is a.cc, %~xc means .cc +# %~nc gives the file name of a given file without extension, %c in this case, so if %c is a.cc, %~nc means a + +NULL= + +# For libxml++ + +!if [call create-lists.bat header libxmlxx.mak libxmlxx_OBJS] +!endif + +!if [for %c in ($(cc_sources)) do @if "%~xc" == ".cc" @call create-lists.bat file libxmlxx.mak vs^$(VSVER)\^$(CFG)\^$(PLAT)\libxmlxx\%~nc.obj] +!endif + +!if [@call create-lists.bat file libxmlxx.mak vs^$(VSVER)\^$(CFG)\^$(PLAT)\libxmlxx\libxml++.res] +!endif + +!if [call create-lists.bat footer libxmlxx.mak] +!endif + +!if [call create-lists.bat header libxmlxx.mak libxmlxx_real_hdrs] +!endif + +!if [for %c in ($(h_sources_public:/=\)) do @call create-lists.bat file libxmlxx.mak ..\libxml++\%c] +!endif + +!if [call create-lists.bat footer libxmlxx.mak] +!endif + +!if [for %d in (examples tests) do @call create-lists.bat header libxmlxx.mak libxmlxx_%d & @(for /f %t in ('dir /ad /b ..\%d') do @call create-lists.bat file libxmlxx.mak vs$(VSVER)\$(CFG)\$(PLAT)\%t.exe) & @call create-lists.bat footer libxmlxx.mak] +!endif + +!if [for %d in (examples tests) do @for /f %t in ('dir /ad /b ..\%d') do @call create-lists.bat header libxmlxx.mak %t_OBJS & @(for %s in (..\%d\%t\*.cc) do @call create-lists.bat file libxmlxx.mak vs$(VSVER)\$(CFG)\$(PLAT)\libxmlxx-%d\%t-%~ns.obj) & @call create-lists.bat footer libxmlxx.mak] +!endif + +!if [echo.>>libxmlxx.mak] +!endif + +!if [for %d in (examples tests) do @for /f %t in ('dir /ad /b ..\%d') do @for %s in (..\%d\%t\*.cc) do @echo vs^$(VSVER)\^$(CFG)\^$(PLAT)\libxmlxx-%d\%t-%~ns.obj: %s>>libxmlxx.mak & @echo. if not exist ^$(@D)\ md ^$(@D)>>libxmlxx.mak & @echo. ^$(CXX) ^$(LIBXMLXX_EX_CFLAGS) ^$(CFLAGS) /Fo^$(@D)\%t-%~ns.obj /Fd^$(@D)\ ^$** /c>>libxmlxx.mak & @echo.>>libxmlxx.mak] +!endif + +!if [for %d in (examples tests) do @for /f %t in ('dir /ad /b ..\%d') do @echo vs^$(VSVER)\^$(CFG)\^$(PLAT)\%t.exe: ^$(LIBXMLXX_LIB) ^$(%t_OBJS)>>libxmlxx.mak & @echo. link ^$(LDFLAGS) ^$** ^$(LIBXML2_LIBS) /out:^$@>>libxmlxx.mak & @echo.>>libxmlxx.mak] +!endif + +!if [echo.>>libxmlxx.mak] +!endif + +!include libxmlxx.mak + +!if [del /f /q libxmlxx.mak] +!endif diff --git a/MSVC_NMake/create-lists.bat b/MSVC_NMake/create-lists.bat new file mode 100644 index 00000000..ef60d5ce --- /dev/null +++ b/MSVC_NMake/create-lists.bat @@ -0,0 +1,42 @@ +@echo off +rem Simple .bat script for creating the NMake Makefile snippets. + +if not "%1" == "header" if not "%1" == "file" if not "%1" == "footer" goto :error_cmd +if "%2" == "" goto error_no_destfile + +if "%1" == "header" goto :header +if "%1" == "file" goto :addfile +if "%1" == "footer" goto :footer + +:header +if "%3" == "" goto error_var +echo %3 = \>>%2 +goto done + +:addfile +if "%3" == "" goto error_file +echo. %3 \>>%2 +goto done + +:footer +echo. $(NULL)>>%2 +echo.>>%2 +goto done + +:error_cmd +echo Specified command '%1' was invalid. Valid commands are: header file footer. +goto done + +:error_no_destfile +echo Destination NMake snippet file must be specified +goto done + +:error_var +echo A name must be specified for using '%1'. +goto done + +:error_file +echo A file must be specified for using '%1'. +goto done + +:done \ No newline at end of file diff --git a/MSVC_NMake/detectenv-msvc.mak b/MSVC_NMake/detectenv-msvc.mak new file mode 100644 index 00000000..ae7c4ba2 --- /dev/null +++ b/MSVC_NMake/detectenv-msvc.mak @@ -0,0 +1,176 @@ +# Change this (or specify PREFIX= when invoking this NMake Makefile) if +# necessary, so that the libs and headers of the dependent third-party +# libraries can be located. For instance, if building from GLib's +# included Visual Studio projects, this should be able to locate the GLib +# build out-of-the-box if they were not moved. GLib's headers will be +# found in $(GLIB_PREFIX)\include\glib-2.0 and +# $(GLIB_PREFIX)\lib\glib-2.0\include and its import library will be found +# in $(GLIB_PREFIX)\lib. + +!if "$(PREFIX)" == "" +PREFIX = ..\..\vs$(VSVER)\$(PLAT) +!endif + +# Location of the PERL interpreter, for running glib-mkenums. glib-mkenums +# needs to be found in $(PREFIX)\bin. Using either a 32-bit or x64 PERL +# interpreter are supported for either a 32-bit or x64 build. + +!if "$(PERL)" == "" +PERL = perl +!endif + +# Location of the Python interpreter, for building introspection. The complete set +# of Python Modules for introspection (the giscanner Python scripts and the _giscanner.pyd +# compiled module) needs to be found in $(PREFIX)\lib\gobject-introspection\giscanner, and +# the g-ir-scanner Python script and g-ir-compiler utility program needs to be found +# in $(PREFIX)\bin, together with any DLLs they will depend on, if those DLLs are not already +# in your PATH. +# Note that the Python interpreter and the introspection modules and utility progam must +# correspond to the build type (i.e. 32-bit Release for 32-bit Release builds, and so on). +# +# For introspection, currently only Python 2.7.x is supported. This may change when Python 3.x +# support is added upstream in gobject-introspection--when this happens, the _giscanner.pyd must +# be the one that is built against the release series of Python that is used here. + +!if "$(PYTHON)" == "" +PYTHON = python +!endif + +# Location of the pkg-config utility program, for building introspection. It needs to be able +# to find the pkg-config (.pc) files so that the correct libraries and headers for the needed libraries +# can be located, using PKG_CONFIG_PATH. Using either a 32-bit or x64 pkg-config are supported for +# either a 32-bit or x64 build. + +!if "$(PKG_CONFIG)" == "" +PKG_CONFIG = pkg-config +!endif + +# The items below this line should not be changed, unless one is maintaining +# the NMake Makefiles. The exception is for the CFLAGS_ADD line(s) where one +# could use his/her desired compiler optimization flags, if he/she knows what is +# being done. + +# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or +# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir) +!if !defined(VCINSTALLDIR) && !defined(WINDOWSSDKDIR) +MSG = ^ +This Makefile is only for Visual Studio 2008 and later.^ +You need to ensure that the Visual Studio Environment is properly set up^ +before running this Makefile. +!error $(MSG) +!endif + +ERRNUL = 2>NUL +_HASH=^# + +!if ![echo VCVERSION=_MSC_VER > vercl.x] \ + && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \ + && ![echo PLAT=Win32 >> vercl.x] \ + && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \ + && ![echo PLAT=x64 >> vercl.x] \ + && ![echo $(_HASH)elif defined(_M_ARM64) >> vercl.x] \ + && ![echo PLAT=arm64 >> vercl.x] \ + && ![echo $(_HASH)endif >> vercl.x] \ + && ![cl -nologo -TC -P vercl.x $(ERRNUL)] +!include vercl.i +!if ![echo VCVER= ^\> vercl.vc] \ + && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc] +!include vercl.vc +!endif +!endif +!if ![del $(ERRNUL) /q/f vercl.x vercl.i vercl.vc] +!endif + +VSVER = 0 +PDBVER = 0 +VSVER_SUFFIX = 0 + +!if $(VCVERSION) > 1499 && $(VCVERSION) < 1600 +PDBVER = 9 +!elseif $(VCVERSION) > 1599 && $(VCVERSION) < 1700 +PDBVER = 10 +!elseif $(VCVERSION) > 1699 && $(VCVERSION) < 1800 +PDBVER = 11 +!elseif $(VCVERSION) > 1799 && $(VCVERSION) < 1900 +PDBVER = 12 +!elseif $(VCVERSION) > 1899 && $(VCVERSION) < 2000 +PDBVER = 14 +!if $(VCVERSION) > 1909 && $(VCVERSION) < 1920 +VSVER_SUFFIX = 1 +VSVER = 15 +!elseif $(VCVERSION) > 1919 && $(VCVERSION) < 1930 +VSVER_SUFFIX = 2 +VSVER = 16 +!elseif $(VCVERSION) > 1929 && $(VCVERSION) < 2000 +VSVER_SUFFIX = 3 +VSVER = 17 +!else +VSVER = $(PDBVER) +!endif +!else +VSVER = $(PDBVER) +!endif + +!if $(VSVER) > 14 && "$(USE_COMPAT_LIBS)" != "" +VSVER_LIB = 150 +!else +VSVER_LIB = $(PDBVER)$(VSVER_SUFFIX) +!endif + +!if "$(VSVER)" == "0" +MSG = ^ +This NMake Makefile set supports Visual Studio^ +9 (2008) through 16 (2019). Your Visual Studio^ +version is not supported. +!error $(MSG) +!endif + +VALID_CFGSET = FALSE +!if "$(CFG)" == "release" || "$(CFG)" == "Release" || "$(CFG)" == "debug" || "$(CFG)" == "Debug" +VALID_CFGSET = TRUE +!endif + +# One may change these items, but be sure to test +# the resulting binaries +!if "$(CFG)" == "release" || "$(CFG)" == "Release" +CFLAGS_ADD_NO_GL = /MD /O2 /MP +CFLAGS_ADD = $(CFLAGS_ADD_NO_GL) /GL +!if "$(VSVER)" != "9" +CFLAGS_ADD = $(CFLAGS_ADD) /d2Zi+ +CFLAGS_ADD_NO_GL = $(CFLAGS_ADD_NO_GL) /d2Zi+ +!if $(VSVER) >= 14 +CFLAGS_ADD = $(CFLAGS_ADD) /utf-8 +CFLAGS_ADD_NO_GL = $(CFLAGS_ADD_NO_GL) /utf-8 +!endif +!endif +!else +CFLAGS_ADD = /MDd /Od +CFLAGS_ADD_NO_GL = $(CFLAGS_ADD) +!endif + +!if "$(PLAT)" == "x64" +LDFLAGS_ARCH = /machine:x64 +!elseif "$(PLAT)" == "arm64" +LDFLAGS_ARCH = /machine:arm64 +!else +LDFLAGS_ARCH = /machine:x86 +!endif + +!if "$(VALID_CFGSET)" == "TRUE" +CFLAGS_NOGL = $(CFLAGS_ADD_NO_GL) /W3 /Zi +CFLAGS = $(CFLAGS_ADD) /W3 /Zi + +LDFLAGS_BASE = $(LDFLAGS_ARCH) /libpath:$(LIBDIR) /DEBUG + +!if "$(CFG)" == "debug" || "$(CFG)" == "Debug" +ARFLAGS_NOLTCG = $(LDFLAGS_ARCH) +ARFLAGS = $(LDFLAGS_ARCH) +LDFLAGS_NOLTCG = $(LDFLAGS_BASE) +LDFLAGS = $(LDFLAGS_BASE) +!else +ARFLAGS_NOLTCG = $(LDFLAGS_ARCH) /LTCG +ARFLAGS = $(ARFLAGS_NOLTCG) /LTCG +LDFLAGS_NOLTCG = $(LDFLAGS_BASE) /opt:ref +LDFLAGS = $(LDFLAGS_NOLTCG) /LTCG +!endif +!endif diff --git a/MSVC_NMake/filelist.am b/MSVC_NMake/filelist.am new file mode 100644 index 00000000..11152a59 --- /dev/null +++ b/MSVC_NMake/filelist.am @@ -0,0 +1,15 @@ +## This file is part of libxml++. + +msvc_nmake_data = \ + MSVC-Builds.md \ + libxml++/libxml++.rc \ + libxml++/libxml++config.h \ + build-rules-msvc.mak \ + config-msvc.mak \ + create-lists-msvc.mak \ + create-lists.bat \ + detectenv-msvc.mak \ + generate-msvc.mak \ + info-msvc.mak \ + install.mak \ + Makefile.vc diff --git a/MSVC_NMake/generate-msvc.mak b/MSVC_NMake/generate-msvc.mak new file mode 100644 index 00000000..80b6d741 --- /dev/null +++ b/MSVC_NMake/generate-msvc.mak @@ -0,0 +1,46 @@ +# NMake Makefile portion for code generation and +# intermediate build directory creation +# Items in here should not need to be edited unless +# one is maintaining the NMake build files. + +# Generate pre-generated resources and configuration headers (builds from GIT) +prep-git-build: pkg-ver.mak + +libxml++\libxml++.rc: ..\configure.ac libxml++\libxml++.rc.in libxml++\libxml++config.h + @if not "$(DO_REAL_GEN)" == "1" if exist pkg-ver.mak del pkg-ver.mak + @if not exist pkg-ver.mak $(MAKE) /f Makefile.vc CFG=$(CFG) prep-git-build + @if "$(DO_REAL_GEN)" == "1" echo Generating $@... + @if "$(DO_REAL_GEN)" == "1" copy "$@.in" "$@" + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\@LIBXMLXX_MAJOR_VERSION\@/$(PKG_MAJOR_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\@LIBXMLXX_MINOR_VERSION\@/$(PKG_MINOR_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\@LIBXMLXX_MICRO_VERSION\@/$(PKG_MICRO_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\@PACKAGE_VERSION\@/$(PKG_MAJOR_VERSION).$(PKG_MINOR_VERSION).$(PKG_MICRO_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\@PACKAGE_NAME\@/libxml++-$(PKG_MAJOR_VERSION).$(PKG_MINOR_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" del $@.bak + +# You may change LIBXMLXX_DISABLE_DEPRECATED if you know what you are doing +libxml++\libxml++config.h: ..\configure.ac ..\libxml++config.h.in + @if not "$(DO_REAL_GEN)" == "1" if exist pkg-ver.mak del pkg-ver.mak + @if not exist pkg-ver.mak $(MAKE) /f Makefile.vc CFG=$(CFG) prep-git-build + @if "$(DO_REAL_GEN)" == "1" echo Generating $@... + @if "$(DO_REAL_GEN)" == "1" copy "..\$(@F).in" "$@" + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\#undef LIBXMLXX_DISABLE_DEPRECATED/\/\* \#undef LIBXMLXX_DISABLE_DEPRECATED \*\//g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\#undef LIBXMLXX_HAVE_EXCEPTION_PTR/\#define LIBXMLXX_HAVE_EXCEPTION_PTR 1/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\#undef LIBXMLXX_MAJOR_VERSION/\#define LIBXMLXX_MAJOR_VERSION $(PKG_MAJOR_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\#undef LIBXMLXX_MINOR_VERSION/\#define LIBXMLXX_MINOR_VERSION $(PKG_MINOR_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" $(PERL) -pi.bak -e "s/\#undef LIBXMLXX_MICRO_VERSION/\#define LIBXMLXX_MICRO_VERSION $(PKG_MICRO_VERSION)/g" $@ + @if "$(DO_REAL_GEN)" == "1" del $@.bak + +pkg-ver.mak: ..\configure.ac + @echo Generating version info Makefile Snippet... + @$(PERL) -00 -ne "print if /AC_INIT\(/" $** | \ + $(PERL) -pe "tr/, /\n/s" | \ + $(PERL) -ne "print if 2 .. 2" | \ + $(PERL) -ne "print /\[(.*)\]/" > ver.txt + @echo @echo off>pkg-ver.bat + @echo.>>pkg-ver.bat + @echo set /p libxmlxx_ver=^>pkg-ver.bat + @echo for /f "tokens=1,2,3 delims=." %%%%a IN ("%libxmlxx_ver%") do (echo PKG_MAJOR_VERSION=%%%%a^& echo PKG_MINOR_VERSION=%%%%b^& echo PKG_MICRO_VERSION=%%%%c)^>$@>>pkg-ver.bat + @pkg-ver.bat + @del ver.txt pkg-ver.bat + $(MAKE) /f Makefile.vc CFG=$(CFG) GENERATE_VERSIONED_FILES=1 libxml++\libxml++.rc diff --git a/MSVC_NMake/info-msvc.mak b/MSVC_NMake/info-msvc.mak new file mode 100644 index 00000000..14205058 --- /dev/null +++ b/MSVC_NMake/info-msvc.mak @@ -0,0 +1,57 @@ +# NMake Makefile portion for displaying config info + +all-build-info: + @echo. + @echo ---------- + @echo Build info + @echo --------- + @echo Build Type: $(CFG) + +help: + @echo. + @echo ============================ + @echo Building glibmm Using NMake + @echo ============================ + @echo nmake /f Makefile.vc CFG=[release^|debug] ^ ^ + @echo. + @echo Where: + @echo ------ + @echo CFG: Required, use CFG=release for an optimized build and CFG=debug + @echo for a debug build. PDB files are generated for all builds. + @echo. + @echo PREFIX: Optional, the path where dependent libraries and tools may be + @echo found, default is ^$(srcrootdir)\..\vs^$(short_vs_ver)\^$(platform), + @echo where ^$(short_vs_ver) is 15 for VS 2017 and so on; and + @echo ^$(platform) is Win32 for 32-bit builds and x64 for x64 builds. + @echo. + @echo ----- + @echo A few options are supported here, namely: + @echo. + @echo USE_COMPAT_LIBS: Use this if you want to use 'vc150' in your DLL and .lib filenames, + @echo instead of using the Visual Studio toolset version. + @echo. + @echo USE_MESON_LIBS: Use DLLs and LIBs of C++ dependencies that are built with Meson, + @echo as applicable. + @echo. + @echo PERL: Full path to PERL interpreter, if not already in PATH, needed to generate + @echo libxml++config.h and libxml++.rc if not already present in .\libxml++. + @echo. + @echo PREFIX: Base directory to look for dependencies and location for where the + @echo build results are copied, default is in ..\..\^$(short_vs_ver)\^$(platform) + @echo. + @echo INCLUDEDIR: Base include directory to look for dependenct headers, + @echo such as libxml2, default is in ^$(PREFIX)\include. + @echo. + @echo LIBDIR: Base directory to look for dependent libraries, such as libxml2, + @echo default is in ^$(PREFIX)\lib. + @echo. + @echo ====== + @echo A 'clean' target is supported to remove all generated files, intermediate + @echo object files and binaries for the specified configuration. + @echo. + @echo An 'install' target is supported to copy the build (DLLs, utility programs, + @echo LIBs, along with the header files) to appropriate locations under ^$(PREFIX). + @echo. + @echo A 'tests' target is supported to build the test programs. + @echo ====== + @echo. diff --git a/MSVC_NMake/install.mak b/MSVC_NMake/install.mak new file mode 100644 index 00000000..1c282f70 --- /dev/null +++ b/MSVC_NMake/install.mak @@ -0,0 +1,18 @@ +# NMake Makefile snippet for copying the built libraries, utilities and headers to +# a path under $(PREFIX). + +install: all + @if not exist $(PREFIX)\bin\ md $(PREFIX)\bin + @if not exist $(PREFIX)\lib\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\include\ md $(PREFIX)\lib\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\include + @if not exist $(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\ @md $(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++ + @for /f %d in ('dir /ad /b ..\libxml++') do @if not exist $(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\%d\ @md $(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\%d + @copy /b "$(LIBXMLXX_DLL)" "$(PREFIX)\bin\" + @copy /b "$(LIBXMLXX_DLL:dll=pdb)" "$(PREFIX)\bin\" + @copy /b "$(LIBXMLXX_LIB)" "$(PREFIX)\lib\" + @for %h in (libxml++.h $(h_root_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\" + @for %h in ($(h_exceptions_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\exceptions\" + @for %h in ($(h_io_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\io\" + @for %h in ($(h_nodes_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\nodes\" + @for %h in ($(h_parsers_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\parsers\" + @for %h in ($(h_validators_sources_public:/=\)) do @copy "..\libxml++\%h" "$(PREFIX)\include\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\libxml++\validators\" + @copy ".\libxml++\libxml++config.h" "$(PREFIX)\lib\libxml++-$(LIBXMLXX_MAJOR_VERSION).$(LIBXMLXX_MINOR_VERSION)\include\" diff --git a/MSVC_Net2010/libxml++/libxml++.rc.in b/MSVC_NMake/libxml++/libxml++.rc.in similarity index 92% rename from MSVC_Net2010/libxml++/libxml++.rc.in rename to MSVC_NMake/libxml++/libxml++.rc.in index e9f81f9f..7f623429 100644 --- a/MSVC_Net2010/libxml++/libxml++.rc.in +++ b/MSVC_NMake/libxml++/libxml++.rc.in @@ -1,7 +1,7 @@ #define APSTUDIO_READONLY_SYMBOLS -#include "afxres.h" +#include "winresrc.h" #undef APSTUDIO_READONLY_SYMBOLS @@ -20,7 +20,7 @@ END 2 TEXTINCLUDE BEGIN - "#include ""afxres.h""\r\n" + "#include ""winresrc.h""\r\n" "\0" END @@ -53,7 +53,7 @@ BEGIN VALUE "FileDescription", "The official C++ wrapper for libxml2" VALUE "FileVersion", "@PACKAGE_VERSION@" VALUE "LegalCopyright", "Distribution is under the LGPL (see COPYING)" - VALUE "OriginalFilename", "libxml++-2.6" + VALUE "OriginalFilename", "libxml++-5.0" VALUE "ProductName", "@PACKAGE_NAME@" VALUE "ProductVersion", "@PACKAGE_VERSION@" END diff --git a/MSVC_NMake/libxml++/meson.build b/MSVC_NMake/libxml++/meson.build new file mode 100644 index 00000000..f4193a66 --- /dev/null +++ b/MSVC_NMake/libxml++/meson.build @@ -0,0 +1,17 @@ +# MSVC_NMake/libxml++ + +# Input: pkg_conf_data, xmlxxconfig_h_meson +# Output: xmlxx_rc + +xmlxx_rc = configure_file( + input: 'libxml++.rc.in', + output: '@BASENAME@', + configuration: pkg_conf_data, +) + +# Make a copy of the generated configuration header in the MSVC project directory. +configure_file( + input: xmlxxconfig_h_meson, + output: 'libxml++config.h', + configuration: pkg_conf_data, +) diff --git a/MSVC_Net2010/README b/MSVC_Net2010/README deleted file mode 100644 index e948c888..00000000 --- a/MSVC_Net2010/README +++ /dev/null @@ -1,14 +0,0 @@ -Building libxml++ with Visual Studio 2010 - -* You will need Visual Studio 2010 (MSVC 10.0). See the MSVC_Net2005/ folder if you want to build libxml++ using Visual Studio .NET 2005 (MSVC 8.0) or the MSVC_Net2008 folder if you want to build libxml++ using Visual Studio .NET 2008 (MSVC 9.0). Earlier versions of the compiler, including 6.0, 7.0 and 7.1 will not work. -* Install the latest Win32 GTK+ Development files from ftp://ftp.gnome.org/pub/GNOME/binaries/win32/gtk+/ -* Build libsigc++ 2.0.6 and glibmm from source -* Add GTK+, libsigc++ and glibmm to the include and lib paths in Visual Studio. -* Load the MSVC_Net2010/libxml++.sln solution. -* Build the entire solution. Run the tests. - -Cedric Gustin -01/26/2005 - -Armin Burgmeier -10/03/2010 diff --git a/MSVC_Net2010/examples/dom_build/dom_build.vcxproj b/MSVC_Net2010/examples/dom_build/dom_build.vcxproj deleted file mode 100644 index 76bc78a0..00000000 --- a/MSVC_Net2010/examples/dom_build/dom_build.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_build - {129ECC08-6D30-4884-B824-4AF96EF0A45C} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_build - dom_build - dom_build - dom_build - - - - /vd2 %(AdditionalOptions) - Disabled - ../../libxml++;../../..;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_build.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../libxml++;../../..;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_build.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../libxml++;../../..;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_build.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../libxml++;../../..;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_build.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_build/dom_build.vcxproj.filters b/MSVC_Net2010/examples/dom_build/dom_build.vcxproj.filters deleted file mode 100644 index 197dc8bb..00000000 --- a/MSVC_Net2010/examples/dom_build/dom_build.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj b/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj deleted file mode 100644 index f08b0b33..00000000 --- a/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_parse_entities - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_parse_entities - dom_parse_entities - dom_parse_entities - dom_parse_entities - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parse_entities.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parse_entities.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parse_entities.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parse_entities.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj.filters b/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj.filters deleted file mode 100644 index 242a752a..00000000 --- a/MSVC_Net2010/examples/dom_parse_entities/dom_parse_entities.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj b/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj deleted file mode 100644 index 7f8b398b..00000000 --- a/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_parser - {947E2653-58AE-4BCC-8A77-B131850C8206} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_parser - dom_parser - dom_parser - dom_parser - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj.filters b/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj.filters deleted file mode 100644 index 8215e5d6..00000000 --- a/MSVC_Net2010/examples/dom_parser/dom_parser.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj b/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj deleted file mode 100644 index 1cbb1e53..00000000 --- a/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_parser_raw - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_parser_raw - dom_parser_raw - dom_parser_raw - dom_parser_raw - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser_raw.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser_raw.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser_raw.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_parser_raw.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj.filters b/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj.filters deleted file mode 100644 index dd7cdfd6..00000000 --- a/MSVC_Net2010/examples/dom_parser_raw/dom_parser_raw.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj b/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj deleted file mode 100644 index 400b2994..00000000 --- a/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_read_write - {6058A05F-D9DA-4965-B506-F927BBF37E75} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_read_write - dom_read_write - dom_read_write - dom_read_write - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_read_write.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_read_write.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_read_write.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_read_write.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj.filters b/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj.filters deleted file mode 100644 index 94fd44d5..00000000 --- a/MSVC_Net2010/examples/dom_read_write/dom_read_write.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj b/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj deleted file mode 100644 index fa77ac1d..00000000 --- a/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dom_xpath - {B0C776B1-FC22-4ADE-88E5-482AE826B353} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dom_xpath - dom_xpath - dom_xpath - dom_xpath - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_xpath.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_xpath.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_xpath.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dom_xpath.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj.filters b/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj.filters deleted file mode 100644 index 57bf26ba..00000000 --- a/MSVC_Net2010/examples/dom_xpath/dom_xpath.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj b/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj deleted file mode 100644 index b58f0008..00000000 --- a/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_dtdvalidation - {6C243796-E9A8-4342-AD70-B32FC1885247} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - dtdvalidation - dtdvalidation - dtdvalidation - dtdvalidation - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dtdvalidation.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dtdvalidation.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)dtdvalidation.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)dtdvalidation.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj.filters b/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj.filters deleted file mode 100644 index 26c95bea..00000000 --- a/MSVC_Net2010/examples/dtdvalidation/dtdvalidation.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/import_node/import_node.vcxproj b/MSVC_Net2010/examples/import_node/import_node.vcxproj deleted file mode 100644 index 2f9065e2..00000000 --- a/MSVC_Net2010/examples/import_node/import_node.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_import_node - {FCEF0A34-7F40-4419-991E-181663D70AC0} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - import_node - import_node - import_node - import_node - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)import_node.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)import_node.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)import_node.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)import_node.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/import_node/import_node.vcxproj.filters b/MSVC_Net2010/examples/import_node/import_node.vcxproj.filters deleted file mode 100644 index d34fcc45..00000000 --- a/MSVC_Net2010/examples/import_node/import_node.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj b/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj deleted file mode 100644 index 5b93fe02..00000000 --- a/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_sax_exception - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - sax_exception - sax_exception - sax_exception - sax_exception - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_exception.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_exception.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_exception.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_exception.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj.filters b/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj.filters deleted file mode 100644 index 02e093e0..00000000 --- a/MSVC_Net2010/examples/sax_exception/sax_exception.vcxproj.filters +++ /dev/null @@ -1,30 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj b/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj deleted file mode 100644 index e99aaef9..00000000 --- a/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_sax_parser - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - sax_parser - sax_parser - sax_parser - sax_parser - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj.filters b/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj.filters deleted file mode 100644 index 6b79fa24..00000000 --- a/MSVC_Net2010/examples/sax_parser/sax_parser.vcxproj.filters +++ /dev/null @@ -1,30 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj b/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj deleted file mode 100644 index b275e366..00000000 --- a/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj +++ /dev/null @@ -1,214 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_sax_parser_build_dom - {394D1FAE-F35F-4A20-9192-2FA598A0D295} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - sax_parser_build_dom - sax_parser_build_dom - sax_parser_build_dom - sax_parser_build_dom - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_build_dom.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_build_dom.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_build_dom.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_build_dom.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - - - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj.filters b/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj.filters deleted file mode 100644 index 1a056a01..00000000 --- a/MSVC_Net2010/examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj.filters +++ /dev/null @@ -1,45 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj b/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj deleted file mode 100644 index 1e4d13aa..00000000 --- a/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj +++ /dev/null @@ -1,209 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_sax_parser_entities - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - sax_parser_entities - sax_parser_entities - sax_parser_entities - sax_parser_entities - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_entities.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_entities.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_entities.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)sax_parser_entities.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj.filters b/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj.filters deleted file mode 100644 index dcb2550b..00000000 --- a/MSVC_Net2010/examples/sax_parser_entities/sax_parser_entities.vcxproj.filters +++ /dev/null @@ -1,30 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - - - Header Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj b/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj deleted file mode 100644 index cdd53ad2..00000000 --- a/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_schemavalidation - {D8027D51-09B4-496E-B2F4-608277E466C9} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - schemavalidation - schemavalidation - schemavalidation - schemavalidation - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)schemavalidation.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)schemavalidation.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)schemavalidation.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)schemavalidation.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj.filters b/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj.filters deleted file mode 100644 index 02c56e77..00000000 --- a/MSVC_Net2010/examples/schemavalidation/schemavalidation.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/textreader/textreader.vcxproj b/MSVC_Net2010/examples/textreader/textreader.vcxproj deleted file mode 100644 index 9d588b78..00000000 --- a/MSVC_Net2010/examples/textreader/textreader.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - examples_textreader - {AE21B35B-954D-454E-AADC-8374DE3B3B68} - examples_dispatcher - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - textreader - textreader - textreader - textreader - - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - EditAndContinue - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)textreader.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX86 - - - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)textreader.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)textreader.exe - true - $(OutDir)$(TargetName).pdb - Console - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - ../../..;../../libxml++;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - Level3 - ProgramDatabase - - - glibmm-vc90-2_4.lib;%(AdditionalDependencies) - $(OutDir)textreader.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - {58b2b53c-c4ff-47fd-817b-095e45b7f7d4} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/examples/textreader/textreader.vcxproj.filters b/MSVC_Net2010/examples/textreader/textreader.vcxproj.filters deleted file mode 100644 index 8e724ad3..00000000 --- a/MSVC_Net2010/examples/textreader/textreader.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/filelist.am b/MSVC_Net2010/filelist.am deleted file mode 100644 index 45506988..00000000 --- a/MSVC_Net2010/filelist.am +++ /dev/null @@ -1,40 +0,0 @@ -## This file is part of libxml++. - -msvc_net2010_data = \ - libxml++.sln \ - README \ - gendef/gendef.cc \ - gendef/gendef.vcxproj \ - gendef/gendef.vcxproj.filters \ - libxml++/libxml++.rc \ - libxml++/libxml++.vcxproj \ - libxml++/libxml++.vcxproj.filters \ - libxml++/libxml++config.h \ - examples/dom_build/dom_build.vcxproj \ - examples/dom_build/dom_build.vcxproj.filters \ - examples/dom_parse_entities/dom_parse_entities.vcxproj \ - examples/dom_parse_entities/dom_parse_entities.vcxproj.filters \ - examples/dom_parser/dom_parser.vcxproj \ - examples/dom_parser/dom_parser.vcxproj.filters \ - examples/dom_parser_raw/dom_parser_raw.vcxproj \ - examples/dom_parser_raw/dom_parser_raw.vcxproj.filters \ - examples/dom_read_write/dom_read_write.vcxproj \ - examples/dom_read_write/dom_read_write.vcxproj.filters \ - examples/dom_xpath/dom_xpath.vcxproj \ - examples/dom_xpath/dom_xpath.vcxproj.filters \ - examples/dtdvalidation/dtdvalidation.vcxproj \ - examples/dtdvalidation/dtdvalidation.vcxproj.filters \ - examples/import_node/import_node.vcxproj \ - examples/import_node/import_node.vcxproj.filters \ - examples/sax_exception/sax_exception.vcxproj \ - examples/sax_exception/sax_exception.vcxproj.filters \ - examples/sax_parser/sax_parser.vcxproj \ - examples/sax_parser/sax_parser.vcxproj.filters \ - examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj \ - examples/sax_parser_build_dom/sax_parser_build_dom.vcxproj.filters \ - examples/sax_parser_entities/sax_parser_entities.vcxproj \ - examples/sax_parser_entities/sax_parser_entities.vcxproj.filters \ - examples/schemavalidation/schemavalidation.vcxproj \ - examples/schemavalidation/schemavalidation.vcxproj.filters \ - examples/textreader/textreader.vcxproj \ - examples/textreader/textreader.vcxproj.filters diff --git a/MSVC_Net2010/gendef/gendef.cc b/MSVC_Net2010/gendef/gendef.cc deleted file mode 100644 index f4ced63e..00000000 --- a/MSVC_Net2010/gendef/gendef.cc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * MICO --- an Open Source CORBA implementation - * Copyright (c) 2003 Harald Bhme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * For more information, visit the MICO Home Page at - * http://www.mico.org/ - */ - -/* Modified by Cedric Gustin on 2006/01/13 : - * Redirect the output of dumpbin to dumpbin.out instead of reading the - * output stream of popen, as it fails with Visual Studio 2005 in - * pre-link build events. - */ - -#include -#include -#include - -using namespace std; - -int main(int argc,char** argv) -{ - if (argc < 4) { - cerr << "Usage: " << argv[0] << " ...." << endl; - return 2; - } - - // CG : Explicitly redirect stdout to dumpbin.out. - string dumpbin = "dumpbin /SYMBOLS /OUT:dumpbin.out"; - int i = 3; - - for(;i fct - def_file << " " << (s+1) << endl; - else - if(strchr(s,'?')!=0 && strncmp(s,"??_G",4)!=0 && strncmp(s,"??_E",4)!=0) { - def_file << " " << s << endl; - } - } - } - } - - // CG : Close dumpbin.out and delete it. - fclose(dump); - remove("dumpbin.out"); - - cout << dumpbin.c_str() << endl; -} diff --git a/MSVC_Net2010/gendef/gendef.vcxproj b/MSVC_Net2010/gendef/gendef.vcxproj deleted file mode 100644 index 6d017604..00000000 --- a/MSVC_Net2010/gendef/gendef.vcxproj +++ /dev/null @@ -1,177 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {07324745-C9BE-4D65-B08A-9C88188C0C28} - Win32Proj - - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - Application - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - false - - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - EditAndContinue - - - $(OutDir)gendef.exe - true - $(OutDir)gendef.pdb - Console - false - - - MachineX86 - - - - - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)gendef.exe - true - Console - true - true - false - - - MachineX86 - - - - - X64 - - - Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebug - - - Level3 - ProgramDatabase - - - $(OutDir)gendef.exe - true - $(OutDir)gendef.pdb - Console - false - - - MachineX64 - - - - - X64 - - - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - MultiThreaded - - - Level3 - ProgramDatabase - - - $(OutDir)gendef.exe - true - Console - true - true - false - - - MachineX64 - - - - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/gendef/gendef.vcxproj.filters b/MSVC_Net2010/gendef/gendef.vcxproj.filters deleted file mode 100644 index ec3f611d..00000000 --- a/MSVC_Net2010/gendef/gendef.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - \ No newline at end of file diff --git a/MSVC_Net2010/libxml++.sln b/MSVC_Net2010/libxml++.sln deleted file mode 100644 index 8983f669..00000000 --- a/MSVC_Net2010/libxml++.sln +++ /dev/null @@ -1,175 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gendef", "gendef\gendef.vcxproj", "{07324745-C9BE-4D65-B08A-9C88188C0C28}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml++-2.6", "libxml++\libxml++.vcxproj", "{58B2B53C-C4FF-47FD-817B-095E45B7F7D4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_build", "examples\dom_build\dom_build.vcxproj", "{129ECC08-6D30-4884-B824-4AF96EF0A45C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_parse_entities", "examples\dom_parse_entities\dom_parse_entities.vcxproj", "{E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_parser", "examples\dom_parser\dom_parser.vcxproj", "{947E2653-58AE-4BCC-8A77-B131850C8206}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_read_write", "examples\dom_read_write\dom_read_write.vcxproj", "{6058A05F-D9DA-4965-B506-F927BBF37E75}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_xpath", "examples\dom_xpath\dom_xpath.vcxproj", "{B0C776B1-FC22-4ADE-88E5-482AE826B353}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dtdvalidation", "examples\dtdvalidation\dtdvalidation.vcxproj", "{6C243796-E9A8-4342-AD70-B32FC1885247}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_import_node", "examples\import_node\import_node.vcxproj", "{FCEF0A34-7F40-4419-991E-181663D70AC0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_sax_exception", "examples\sax_exception\sax_exception.vcxproj", "{1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_sax_parser", "examples\sax_parser\sax_parser.vcxproj", "{A665E2E3-4148-4389-B5C4-271AFE4BC1B7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_sax_parser_build_dom", "examples\sax_parser_build_dom\sax_parser_build_dom.vcxproj", "{394D1FAE-F35F-4A20-9192-2FA598A0D295}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_sax_parser_entities", "examples\sax_parser_entities\sax_parser_entities.vcxproj", "{C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_textreader", "examples\textreader\textreader.vcxproj", "{AE21B35B-954D-454E-AADC-8374DE3B3B68}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_schemavalidation", "examples\schemavalidation\schemavalidation.vcxproj", "{D8027D51-09B4-496E-B2F4-608277E466C9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "examples_dom_parser_raw", "examples\dom_parser_raw\dom_parser_raw.vcxproj", "{D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Debug|Win32.ActiveCfg = Debug|Win32 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Debug|Win32.Build.0 = Debug|Win32 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Debug|x64.ActiveCfg = Debug|x64 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Debug|x64.Build.0 = Debug|x64 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Release|Win32.ActiveCfg = Release|Win32 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Release|Win32.Build.0 = Release|Win32 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Release|x64.ActiveCfg = Release|x64 - {07324745-C9BE-4D65-B08A-9C88188C0C28}.Release|x64.Build.0 = Release|x64 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Debug|Win32.ActiveCfg = Debug|Win32 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Debug|Win32.Build.0 = Debug|Win32 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Debug|x64.ActiveCfg = Debug|x64 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Debug|x64.Build.0 = Debug|x64 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Release|Win32.ActiveCfg = Release|Win32 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Release|Win32.Build.0 = Release|Win32 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Release|x64.ActiveCfg = Release|x64 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4}.Release|x64.Build.0 = Release|x64 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Debug|Win32.ActiveCfg = Debug|Win32 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Debug|Win32.Build.0 = Debug|Win32 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Debug|x64.ActiveCfg = Debug|x64 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Debug|x64.Build.0 = Debug|x64 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Release|Win32.ActiveCfg = Release|Win32 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Release|Win32.Build.0 = Release|Win32 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Release|x64.ActiveCfg = Release|x64 - {129ECC08-6D30-4884-B824-4AF96EF0A45C}.Release|x64.Build.0 = Release|x64 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Debug|Win32.ActiveCfg = Debug|Win32 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Debug|Win32.Build.0 = Debug|Win32 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Debug|x64.ActiveCfg = Debug|x64 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Debug|x64.Build.0 = Debug|x64 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Release|Win32.ActiveCfg = Release|Win32 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Release|Win32.Build.0 = Release|Win32 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Release|x64.ActiveCfg = Release|x64 - {E7989806-1E3E-45AA-AE0D-E6C9250EDDF5}.Release|x64.Build.0 = Release|x64 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Debug|Win32.ActiveCfg = Debug|Win32 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Debug|Win32.Build.0 = Debug|Win32 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Debug|x64.ActiveCfg = Debug|x64 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Debug|x64.Build.0 = Debug|x64 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Release|Win32.ActiveCfg = Release|Win32 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Release|Win32.Build.0 = Release|Win32 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Release|x64.ActiveCfg = Release|x64 - {947E2653-58AE-4BCC-8A77-B131850C8206}.Release|x64.Build.0 = Release|x64 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Debug|Win32.ActiveCfg = Debug|Win32 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Debug|Win32.Build.0 = Debug|Win32 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Debug|x64.ActiveCfg = Debug|x64 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Debug|x64.Build.0 = Debug|x64 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Release|Win32.ActiveCfg = Release|Win32 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Release|Win32.Build.0 = Release|Win32 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Release|x64.ActiveCfg = Release|x64 - {6058A05F-D9DA-4965-B506-F927BBF37E75}.Release|x64.Build.0 = Release|x64 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Debug|Win32.ActiveCfg = Debug|Win32 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Debug|Win32.Build.0 = Debug|Win32 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Debug|x64.ActiveCfg = Debug|x64 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Debug|x64.Build.0 = Debug|x64 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Release|Win32.ActiveCfg = Release|Win32 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Release|Win32.Build.0 = Release|Win32 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Release|x64.ActiveCfg = Release|x64 - {B0C776B1-FC22-4ADE-88E5-482AE826B353}.Release|x64.Build.0 = Release|x64 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Debug|Win32.ActiveCfg = Debug|Win32 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Debug|Win32.Build.0 = Debug|Win32 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Debug|x64.ActiveCfg = Debug|x64 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Debug|x64.Build.0 = Debug|x64 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Release|Win32.ActiveCfg = Release|Win32 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Release|Win32.Build.0 = Release|Win32 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Release|x64.ActiveCfg = Release|x64 - {6C243796-E9A8-4342-AD70-B32FC1885247}.Release|x64.Build.0 = Release|x64 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Debug|Win32.ActiveCfg = Debug|Win32 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Debug|Win32.Build.0 = Debug|Win32 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Debug|x64.ActiveCfg = Debug|x64 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Debug|x64.Build.0 = Debug|x64 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Release|Win32.ActiveCfg = Release|Win32 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Release|Win32.Build.0 = Release|Win32 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Release|x64.ActiveCfg = Release|x64 - {FCEF0A34-7F40-4419-991E-181663D70AC0}.Release|x64.Build.0 = Release|x64 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Debug|Win32.ActiveCfg = Debug|Win32 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Debug|Win32.Build.0 = Debug|Win32 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Debug|x64.ActiveCfg = Debug|x64 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Debug|x64.Build.0 = Debug|x64 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Release|Win32.ActiveCfg = Release|Win32 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Release|Win32.Build.0 = Release|Win32 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Release|x64.ActiveCfg = Release|x64 - {1DA79E56-7C9E-4D77-BF66-C8CD03BB2D58}.Release|x64.Build.0 = Release|x64 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Debug|Win32.ActiveCfg = Debug|Win32 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Debug|Win32.Build.0 = Debug|Win32 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Debug|x64.ActiveCfg = Debug|x64 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Debug|x64.Build.0 = Debug|x64 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Release|Win32.ActiveCfg = Release|Win32 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Release|Win32.Build.0 = Release|Win32 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Release|x64.ActiveCfg = Release|x64 - {A665E2E3-4148-4389-B5C4-271AFE4BC1B7}.Release|x64.Build.0 = Release|x64 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Debug|Win32.ActiveCfg = Debug|Win32 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Debug|Win32.Build.0 = Debug|Win32 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Debug|x64.ActiveCfg = Debug|x64 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Debug|x64.Build.0 = Debug|x64 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Release|Win32.ActiveCfg = Release|Win32 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Release|Win32.Build.0 = Release|Win32 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Release|x64.ActiveCfg = Release|x64 - {394D1FAE-F35F-4A20-9192-2FA598A0D295}.Release|x64.Build.0 = Release|x64 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Debug|Win32.ActiveCfg = Debug|Win32 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Debug|Win32.Build.0 = Debug|Win32 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Debug|x64.ActiveCfg = Debug|x64 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Debug|x64.Build.0 = Debug|x64 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Release|Win32.ActiveCfg = Release|Win32 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Release|Win32.Build.0 = Release|Win32 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Release|x64.ActiveCfg = Release|x64 - {C023B6BA-4F3D-4FD4-ACC3-732120ACD2C9}.Release|x64.Build.0 = Release|x64 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Debug|Win32.ActiveCfg = Debug|Win32 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Debug|Win32.Build.0 = Debug|Win32 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Debug|x64.ActiveCfg = Debug|x64 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Debug|x64.Build.0 = Debug|x64 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Release|Win32.ActiveCfg = Release|Win32 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Release|Win32.Build.0 = Release|Win32 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Release|x64.ActiveCfg = Release|x64 - {AE21B35B-954D-454E-AADC-8374DE3B3B68}.Release|x64.Build.0 = Release|x64 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Debug|Win32.ActiveCfg = Debug|Win32 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Debug|Win32.Build.0 = Debug|Win32 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Debug|x64.ActiveCfg = Debug|x64 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Debug|x64.Build.0 = Debug|x64 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Release|Win32.ActiveCfg = Release|Win32 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Release|Win32.Build.0 = Release|Win32 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Release|x64.ActiveCfg = Release|x64 - {D8027D51-09B4-496E-B2F4-608277E466C9}.Release|x64.Build.0 = Release|x64 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Debug|Win32.ActiveCfg = Debug|Win32 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Debug|Win32.Build.0 = Debug|Win32 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Debug|x64.ActiveCfg = Debug|x64 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Debug|x64.Build.0 = Debug|x64 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Release|Win32.ActiveCfg = Release|Win32 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Release|Win32.Build.0 = Release|Win32 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Release|x64.ActiveCfg = Release|x64 - {D6AC5DAE-FCDD-4B03-93DC-7588AA3F10F0}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/MSVC_Net2010/libxml++/libxml++.vcxproj b/MSVC_Net2010/libxml++/libxml++.vcxproj deleted file mode 100644 index 37137f48..00000000 --- a/MSVC_Net2010/libxml++/libxml++.vcxproj +++ /dev/null @@ -1,413 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - xml++-2.6 - {58B2B53C-C4FF-47FD-817B-095E45B7F7D4} - glibmm - Win32Proj - - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - DynamicLibrary - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.30319.1 - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\ - true - xml++-vc100-d-2_6 - xml++-vc100-d-2_6 - xml++-vc100-2_6 - xml++-vc100-2_6 - - - - /vd2 %(AdditionalOptions) - Disabled - .;../..;%(AdditionalIncludeDirectories) - LIBXMLPP_BUILD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - $(IntDir) - Level3 - EditAndContinue - - - Generate libxml++ def file - $(SolutionDir)gendef\$(Platform)\$(Configuration)\gendef $(Platform)\$(Configuration)\$(ProjectName).def $(TargetFileName) $(IntDir)*.obj $(IntDir)exceptions\*.obj $(IntDir)io\*.obj $(IntDir)nodes\*.obj $(IntDir)parsers\*.obj $(IntDir)validators\*.obj - - - libxml2.lib;glibmm-vc100-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)xml++-vc100-d-2_6.dll - $(Platform)\$(Configuration)\$(ProjectName).def - true - false - - - - - - - /vd2 %(AdditionalOptions) - .;../..;%(AdditionalIncludeDirectories) - LIBXMLPP_BUILD;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - $(IntDir) - Level3 - ProgramDatabase - - - Generate libxml++ def file - $(SolutionDir)gendef\$(Platform)\$(Configuration)\gendef $(Platform)\$(Configuration)\$(ProjectName).def $(TargetFileName) $(IntDir)*.obj $(IntDir)exceptions\*.obj $(IntDir)io\*.obj $(IntDir)nodes\*.obj $(IntDir)parsers\*.obj $(IntDir)validators\*.obj - - - libxml2.lib;glibmm-vc100-2_4.lib;%(AdditionalDependencies) - $(OutDir)xml++-vc100-2_6.dll - $(Platform)\$(Configuration)\$(ProjectName).def - false - - - - - - - X64 - - - /vd2 %(AdditionalOptions) - Disabled - .;../..;%(AdditionalIncludeDirectories) - LIBXMLPP_BUILD;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - true - - - $(IntDir) - Level3 - ProgramDatabase - - - Generate libxml++ def file - $(SolutionDir)gendef\$(Platform)\$(Configuration)\gendef $(Platform)\$(Configuration)\$(ProjectName).def $(TargetFileName) $(IntDir)*.obj $(IntDir)exceptions\*.obj $(IntDir)io\*.obj $(IntDir)nodes\*.obj $(IntDir)parsers\*.obj $(IntDir)validators\*.obj - - - libxml2.lib;glibmm-vc100-d-2_4.lib;%(AdditionalDependencies) - $(OutDir)xml++-vc100-d-2_6.dll - $(Platform)\$(Configuration)\$(ProjectName).def - true - false - - - MachineX64 - - - - - X64 - - - /vd2 %(AdditionalOptions) - .;../..;%(AdditionalIncludeDirectories) - LIBXMLPP_BUILD;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - - $(IntDir) - Level3 - ProgramDatabase - - - Generate libxml++ def file - $(SolutionDir)gendef\$(Platform)\$(Configuration)\gendef $(Platform)\$(Configuration)\$(ProjectName).def $(TargetFileName) $(IntDir)*.obj $(IntDir)exceptions\*.obj $(IntDir)io\*.obj $(IntDir)nodes\*.obj $(IntDir)parsers\*.obj $(IntDir)validators\*.obj - - - libxml2.lib;glibmm-vc100-2_4.lib;%(AdditionalDependencies) - $(OutDir)xml++-vc100-2_6.dll - $(Platform)\$(Configuration)\$(ProjectName).def - false - - - MachineX64 - - - - - $(IntDir) - $(IntDir) - $(IntDir) - $(IntDir) - - - $(IntDir) - $(IntDir) - $(IntDir) - $(IntDir) - - - $(IntDir) - $(IntDir) - $(IntDir) - $(IntDir) - - - $(IntDir) - $(IntDir) - $(IntDir) - $(IntDir) - - - $(IntDir) - $(IntDir) - $(IntDir) - $(IntDir) - - - - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - - - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - - - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - - - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - $(IntDir)exceptions/ - - - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - - - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - - - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - - - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - $(IntDir)io/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - $(IntDir)nodes/ - - - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - - - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - - - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - - - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - $(IntDir)parsers/ - - - $(IntDir)validators/ - $(IntDir)validators/ - $(IntDir)validators/ - $(IntDir)validators/ - - - - $(IntDir)validators/ - $(IntDir)validators/ - $(IntDir)validators/ - $(IntDir)validators/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {07324745-c9be-4d65-b08a-9c88188c0c28} - false - - - - - - \ No newline at end of file diff --git a/MSVC_Net2010/libxml++/libxml++.vcxproj.filters b/MSVC_Net2010/libxml++/libxml++.vcxproj.filters deleted file mode 100644 index b4212dd0..00000000 --- a/MSVC_Net2010/libxml++/libxml++.vcxproj.filters +++ /dev/null @@ -1,233 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {cc96b287-b76c-4e11-aa5c-ff6ac19dd972} - - - {7385d814-0522-4907-82ad-1cd50a85a5d7} - - - {af9f9408-ae6e-45af-81ba-31fe29b59201} - - - {82e6457e-ad05-4d96-a817-2249be8d83b1} - - - {61c1abc9-f870-4d8a-b83f-0ad60fb6fffa} - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {fd96338f-997a-4f3c-ab2f-e8c6e1e2d1b7} - - - {151f1608-6062-4c50-9dfe-3cbc25f91b5c} - - - {b6a1457d-0d4d-4a44-b87f-8df64ca9e959} - - - {ce47077c-1131-4929-b116-616bf6b9d6fd} - - - {da70c9fb-5a3c-4142-9d58-0c8f62b5ae97} - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files\exceptions - - - Source Files\exceptions - - - Source Files\exceptions - - - Source Files\exceptions - - - Source Files\io - - - Source Files\io - - - Source Files\io - - - Source Files\io - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\nodes - - - Source Files\parsers - - - Source Files\parsers - - - Source Files\parsers - - - Source Files\parsers - - - Source Files\validators - - - Source Files\validators - - - Source Files\validators - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files\exceptions - - - Header Files\exceptions - - - Header Files\exceptions - - - Header Files\exceptions - - - Header Files\io - - - Header Files\io - - - Header Files\io - - - Header Files\io - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\nodes - - - Header Files\parsers - - - Header Files\parsers - - - Header Files\parsers - - - Header Files\parsers - - - Header Files\validators - - - Header Files\validators - - - Header Files\validators - - - - - Resource Files - - - \ No newline at end of file diff --git a/Makefile.am b/Makefile.am index 2779bb72..b7d45e28 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## This file is part of libxml++. -ACLOCAL_AMFLAGS = -I macros ${ACLOCAL_FLAGS} +ACLOCAL_AMFLAGS = -I build ${ACLOCAL_FLAGS} DISTCHECK_CONFIGURE_FLAGS = --enable-warnings=fatal if ENABLE_DOCUMENTATION @@ -16,13 +16,34 @@ nodist_library_config_HEADERS = libxml++config.h pkgconfigdir = $(libdir)/pkgconfig nodist_pkgconfig_DATA = $(LIBXMLXX_MODULE_NAME).pc -include $(srcdir)/MSVC_Net2010/filelist.am +include $(srcdir)/MSVC_NMake/filelist.am -dist_noinst_DATA = $(addprefix MSVC_Net2010/,$(msvc_net2010_data)) +dist_noinst_DATA = \ + $(addprefix MSVC_NMake/,$(msvc_nmake_data)) \ + README.md dist_noinst_SCRIPTS = autogen.sh -DISTCLEANFILES = MSVC_Net2010/libxml++/libxml++config.h +DISTCLEANFILES = MSVC_NMake/libxml++/libxml++config.h + +# Distribute files needed when building libxml++ with Meson. +EXTRA_DIST = \ + meson.build \ + meson_options.txt \ + libxml++config.h.meson \ + MSVC_NMake/libxml++/meson.build \ + docs/manual/can_use_xmllint.xml \ + docs/manual/insert_example_code.py \ + docs/manual/meson.build \ + docs/reference/meson.build \ + examples/meson.build \ + libxml++/meson.build \ + subprojects/libxml2.wrap \ + subprojects/mm-common.wrap \ + tests/meson.build \ + tools/build_scripts/tutorial-custom-cmd.py \ + tools/conf_tests/have_exception_ptr.cc \ + untracked/README # Optional: auto-generate the ChangeLog file from the git log on make dist -include $(top_srcdir)/macros/dist-changelog.am +include $(top_srcdir)/build/dist-changelog.am diff --git a/NEWS b/NEWS index 3f03781a..aae1fdff 100644 --- a/NEWS +++ b/NEWS @@ -1,8 +1,287 @@ +5.4.0 (stable): + +* Node: Add eval_xpath(). + (Kjell Ahlstedt) Issue #66 (Marie Preusse) + +Meson build: +* Require meson >= 0.62. +* Use Meson's pkgconfig module instead of the libxml++.pc.in template. + (Kjell Ahlstedt) + + +5.2.1 (stable): + +* Parser: Ignore deprecation of xmlParserCtxt members. + (Kjell Ahlstedt) + +Documentation: +* Don't link to removed developer-old.gnome.org. + (Kjell Ahlstedt) + +Meson build: +* Use libxml2 meson build when libxml2 is built as a subproject. + (Andrew Potter) Issue #67, Pull request #68 +* Require python3 >= 3.7. That's what Meson requires. + (Kjell Ahlstedt) + +5.2.0 (stable): + +* Use callback functions with C linkage + (Kjell Ahlstedt) Issue glibmm#1 (Murray Cumming) + +Documentation: +* Update Visual Studio build docs + (Chun-wei Fan) Pull request #52 +* Remove AUTHORS and add general information to README.md + (Kjell Ahlstedt) Issue gtkmm#140 +* Parser docs: Add a link to parser options +* README.md: Add info about building the documentation + (Kjell Ahlstedt) + +Meson build: +* Cleanup and fix libxml2 dep search + (Chun-wei Fan) Pull request #51 +* Don't fail if warning_level=everything + (Daniel Boles, Kjell Ahlstedt) Merge request gtkmm!87 +* Add bcrypt dependency when libxml2 is a subproject + Issue #64 (Kjell Ahlstedt) + (Andrew Potter) Pull request #65 +* Don't require the 'dot' command to build the documentation + (Kjell Ahlstedt) Issue libsigcplusplus#98 +* Add the build-manual option + (Kjell Ahlstedt) + +Build: +* Make it compatible with libxml2 >= 2.12.0 + by modifying #include directives + (Kjell Ahlstedt) + + +5.0.3 (stable): + +* exception: Fix linking on MinGW + (Chun-wei Fan) Issue #45 (Rosen Penev) + (Chun-wei Fan) Pull request #46 +* headers: Drop LIBXMLPP_API from 'friend' members + (Chun-wei Fan) Pull request #47 + +Meson build: +* Detect if we build from a git subtree + (William Roy) Merge request gtkmm!72 +* Don't copy files with configure_file() + (Kjell Ahlstedt) +* Fix the evaluation of is_git_build on Windows + (Kjell Ahlstedt) Issue gtkmm#131 (William Roy) + + +5.0.2 (stable): + +* Document, Node: Recognize HTML documents + (Kjell Ahlstedt) Issue #23 (rkd77) +* Parsers: Avoid std::getline for istream inputs + (Andrew Potter) Pull request #28 +* Many small updates, suggested by the clang-tidy program + (Rosen Penev) Pull requests #33-#35, #37-#43 + +Build: +* Meson build: When mm-common >= 1.0.4 is used, Perl is not required + (Kjell Ahlstedt) +* Win32: Don't include afxres.h in resources +* Support Visual Studio 2022 + (Chun-wei Fan) +* Meson build: Specify 'check' option in run_command() + Will be necessary with future versions of Meson. + (Kjell Ahlstedt) +* Meson build: Avoid configuration warnings + (Kjell Ahlstedt, Rosen Penev) Pull request #27 +* docs/manual: Sort example file lists + See https://gitlab.gnome.org/GNOME/gtkmm-documentation/-/merge_requests/15 + by Bernhard M. Wiedemann + (Kjell Ahlstedt) +* Meson build: Enable static building on windows + (Andrew Potter) Pull request #29 +* Meson build: Require meson >= 0.60.0 +* Meson build: libxml2 can be built as a subproject + (Andrew Potter) Pull request #30 +* NMake Makefiles: Remove dependency on msvc_recommended_pragmas.h +* NMake Makefiles: Make things more configurable + (Chun-wei Fan) Issue #44 (lxxxd) + +Documentation: +* docs/manual: Upgrade from DocBook 4.1 to DocBook 5.0 + (Kjell Ahlstedt) +* MSVC_NMake/README: Document dependency placement + (Chun-wei Fan) Issue #44 (lxxxd) + + +5.0.1 (stable): + +Build: +* libxml++config.h.*: Don't dllimport on MinGW + (Chun-wei Fan) Issue gtkmm#90 (Lukas K.) +* Meson build: Make it possible to use libxml++ as a subproject + (Kjell Ahlstedt) +* Meson build: No implicit_include_directories + (Kjell Ahlstedt) +* MSVC build: Export classes selectively + (Chun-wei Fan) + +Documentation: +* docs/index.md: Describe the different libxml++ ABIs + (Kjell Ahlstedt) Issue #20 (Tom Schoonjans) + + +5.0.0 (stable): + +This is the first stable release in the libxml++-5.0 ABI series. +It is parallel-installable with the libxml++-2.6, libxml++-3.0 +and libxml++-4.0 ABIs. + +The tarball for 5.0.0 has been created with 'meson dist'. +If you build with Autotools from the tarball, please read +the relevant part of the README file. + +Build: +* Add NMake Makefiles + Remove Visual Studio 2010 projects + (Chun-wei Fan) Pull request #10 +* Use __declspec(dllexport) when building on Visual Studio + Stop using gendef.exe + (Chun-wei Fan) Pull request #15 +* Add support for building with Meson + (Kjell Ahlstedt, Chun-wei Fan) Pull request #16, #17, issue #19 + + +4.9.1 (unstable): + +* Change ABI name from libxml++-4.0 to libxml++-5.0 + There is also a libxml++-4-0 branch for the libxml++-4.0 ABI, + which still uses glibmm-2.64. + And there is a libxml++-3-0 branch for the libxml++-3.0 ABI, + which still uses glibmm-2.4. +* Build: Remove dependency on glibmm and don't use Glib::ustring + For now, the API uses an xmlpp::ustring alias of std::string + where it previously used Glib::ustring. + +3.9.1 (unstable): + +* Change ABI name to libxml++-4.0 + There is also a libxml++-3-2 branch for the libxml++-3.0 ABI, + which still uses glibmm-2.4. +* Build: + - Use glibmm-2.64 instead of glibmm-2.4. + - Require C++17. +* Parser: Make some methods const + +3.2.0 (stable): + +* Document, DomParser: Improve XInclude processing: + Document: + Add process_xinclude() overload that takes a fixup_base_uris parameter. + DomParser: + Add set/get_xinclude_options() and add optional XInclude processing to the + parse methods. + (Kjell Ahlstedt) Bug 781566 +* Add explicit keyword to some single-parameter constructors. + (Murray Cumming) +* tests: Don't require C++17 + (Kjell Ahlstedt) +* Build: Fix srcdir != buildir build. + (Kjell Ahlstedt, Murray Cumming) + +3.0.1 (stable): + +* Element::remove_attribute(): Delete the C++ wrapper + (Harald Schmalzl, Kjell Ahlstedt) Bug #768404. + +3.0.0 (stable): + +* This is the first stable release of libxml++-3.0. ABI and API are + incompatible with libxml++-2.6. These two series of libxml++ can be + installed in parallel. + Applications that want to upgrade from libxml++-2.6 to libxml++-3.0 + must change their pkg-config check to libxml++-3.0. + (Kjell Ahlstedt) Bug #754673. + +* This release is identical to the unstable 2.91.3, except for the so name, + which has now been bumped. + (Kjell Ahlstedt) Bug #760574 (Dominique Leuenberger) + +2.91.3 (unstable): + +* Element: Remove a redundant nullptr check + (Renu Tyagi) Bug #757515 + +* Use scoped enums (enum class) instead of unscoped enums +* Document: Test for nullptr in a constructor +* DomParser: Make operator bool() explicit + (Kjell Ahlstedt) + +* The ABI and API are not identical to libxml++ 2.91.2. + There may be more changes in ABI and/or API before the first stable + libxml++-3.0 release. + +2.91.2 (unstable): + +* Remove the preprocessor constant LIBXMLCPP_EXCEPTIONS_ENABLED. + It was always 1. + +* Add a config-time test for support of std::exception_ptr. Don't try to + use std::exception_ptr on a system where it does not exist. + This includes re-implementing the wrapped_exception class and the + raise() and clone() methods in xmlpp::exception and its subclasses. + (Daniel Trebbien, Kjell Ahlstedt) Bug #757042 (Michael Biebl) + +* The ABI is not identical to that of libxml++ 2.91.1. + There may be more changes in ABI and/or API before the first stable + libxml++-3.0 release. + +2.91.1 (unstable): + +* Renamed ABI from libxml++-2.6 to libxml++-3.0. + This requires applications to change their pkg-config check to libxml++-3.0 + when they wish to use libxml++ 2.9x or 3.x instead of libxml++ 2.x. + (Kjell Ahlstedt) Bug #754673. + There may be more changes in ABI and/or API before the first stable + libxml++-3.0 release. + +* Node: Add const_NodeList and use it in a const version of get_children(). + Add const_NodeSet and use it in a const version of find(). + Replace xmlpp::NodeSet by xmlpp::Node::NodeSet. + Element: Add const_Attribute_list and use it in a const version of + get_attributes(). + (Kjell Ahlstedt) Bug #338907 (Marcos Mayorga) +* Document: Add a non-const version of get_root_node(). Let the const version + return a const pointer. + (Knut Aksel Røysland) Bug #632522 +* Element: Add a non-const version of get_attribute(). Let the const version + return a const pointer. + (Knut Aksel Røysland) Bug #632524 +* Replace the deprecated std::auto_ptr by std::unique_ptr + (Kjell Ahlstedt) Bug #753123 +* DomParser: The default behaviour is to throw both parse errors and + validity errors in an exception instead of printing some messages on stderr. +* Parser: Some protected data has become private. +* Several classes: Some virtual methods have become non-virtual, and some + non-virtual methods have become virtual. +* Remove class xmlpp::wrapped_exception and the deprecated classes + Schema and SchemaValidator. +* xmlpp::exception and its subclasses: Remove Raise() and Clone(). +* SaxParser: Start each parsing with a new Document for entity resolution. +* Move all Node::add_child*() methods to Element and rename them to + add_child_element*(). +* Attribute: Move set_value() to AttributeNode. +* Use std::string instead of Glib::ustring for filenames. +* Node: Replace remove_child() by remove_node(). +* Move some code from DtdValidator to Dtd. +* Element: Rename set/get_child_text() to set/get_first_child_text(). + + 2.39.2 (unstable): * SaxParser: Fix “double free or corruption” if a std::exception is thrown by a handler method. - (Daniel Trebbien, Kjell Ahlstedt) + (Daniel Trebbien, Kjell Ahlstedt) Bug #753570 * Replace some (deprecated in C++11) std::auto_ptr by std::unique_ptr. There are still some auto_ptrs in header files bug replacing them would break ABI. @@ -17,7 +296,7 @@ * Fix the build with C++11 compilers, such as MS Visual C++ 2013 - Implicit conversions from streams to bool are no longer allowed.) - (Mikhail Titov) + (Mikhail Titov) Bug #748658 * Build: Disable deprecated API in dependencies if --enable-warnings=fatal (Kjell Ahlstedt) * Build: Require libxml2 2.7.7 or later diff --git a/README b/README deleted file mode 100644 index 7474a6aa..00000000 --- a/README +++ /dev/null @@ -1,21 +0,0 @@ -libxml++ -------------- - -This library provides a C++ interface to XML files. It uses libxml 2 to access -the XML files, and in order to configure libxml++ you must have both libxml and -pkg-config installed. - -To get the latest version of libxml++, see -http://libxmlplusplus.sourceforge.net/ -To contact the developers, send e-mail to the mailing list. We welcome patches, -but it helps to discuss them first. - -Read the file 'INSTALL' for instructions to compile and install the library. - -See the examples directory for example code. - -Use pkg-config to discover the necessary include and linker arguments. For -instance, - pkg-config libxml++-2.6 --cflags --libs -Ideally you would use PKG_CHECK_MODULES in your configure.ac file. -See http://www.openismus.com for generic help with that. diff --git a/README.md b/README.md new file mode 100644 index 00000000..15e40c8b --- /dev/null +++ b/README.md @@ -0,0 +1,181 @@ +# libxml++ +C++ interface to libxml2 and XML files. + +# Introduction + +libxml++ (a.k.a. libxmlplusplus) provides a C++ interface to XML files. It uses +libxml2 to access the XML files, and in order to configure libxml++ you must +have both libxml2 and pkg-config installed. + +libxml++-2.6, libxml++-3.0, libxml++-4.0 and libxml++-5.0 are different +parallel-installable ABIs. This file describes libxml++-5.0. + +See the examples directory for example code. + +Use pkg-config to discover the necessary include and linker arguments. +For instance, +``` + pkg-config libxml++-5.0 --cflags --libs +``` +If you build with Autotools, ideally you would use PKG_CHECK_MODULES in your +configure.ac file. + +# General information + +Web site + - https://libxmlplusplus.github.io/libxmlplusplus/ + +Download location + - https://download.gnome.org/sources/libxml++/ (until 5.4.0) + - https://github.com/libxmlplusplus/libxmlplusplus/releases/ + +Reference documentation + - https://libxmlplusplus.github.io/libxmlplusplus/reference/html/ + +Tarballs contain reference documentation. In tarballs generated with Meson, +see the untracked/docs/reference/html directory. + +Discussion on GNOME's discourse forum + - https://discourse.gnome.org/tag/cplusplus + - https://discourse.gnome.org/c/platform + +Git repository + - https://github.com/libxmlplusplus/libxmlplusplus + +Bugs can be reported to + - https://github.com/libxmlplusplus/libxmlplusplus/issues + +Patches can be submitted to + - https://github.com/libxmlplusplus/libxmlplusplus/pulls + +# Building + +Whenever possible, you should use the official binary packages approved by the +supplier of your operating system, such as your Linux distribution. + +## Building the documentation + +The reference documentaion is built with Doxygen. + +The manual is a DocBook 5.0 document. These packages are recommended when building +the manual (can have other names in other distros): + - docbook5-xml (Ubuntu and Debian) or docbook5-schemas (Fedora) + - docbook-xsl (Ubuntu and Debian) or docbook-style-xsl (Fedora) + +It may be possible to build without these packages, but it will be slow and error prone. +The `xmllint` command is told to read files from http://docbook.org. +The `xsltproc` command is told to read files from http://docbook.sourceforge.net. +The commands first search for local copies of those files. If local copies exist +and are installed at expected locations, the commands make no network accesses. + +## Building on Windows + +See [MSVC-Builds](MSVC_NMake/MSVC-Builds.md) + +## Building from a release tarball + +Extract the tarball and go to the extracted directory: +``` + $ tar xf libxml++-@LIBXMLXX_VERSION@.tar.xz + $ cd libxml++-@LIBXMLXX_VERSION@ +``` + +It's easiest to build with Meson, if the tarball was made with Meson, +and to build with Autotools, if the tarball was made with Autotools. +Then you don't have to use maintainer-mode. + +How do you know how the tarball was made? If it was made with Meson, +it contains files in untracked/docs/ and other subdirectories +of untracked/. + +### Building from a tarball with Meson + +Don't call the builddir 'build'. There is a directory called 'build' with +files used by Autotools. +``` + $ meson setup --prefix /some_directory --libdir lib your_builddir . + $ cd your_builddir +``` +If the tarball was made with Autotools, you must enable maintainer-mode: +``` + $ meson configure -Dmaintainer-mode=true +``` +Then, regardless of how the tarball was made: +``` + $ ninja + $ ninja install +``` +You can run the tests like so: +``` + $ ninja test +``` + +### Building from a tarball with Autotools + +If the tarball was made with Autotools: +``` + $ ./configure --prefix=/some_directory +``` +If the tarball was made with Meson, you must enable maintainer-mode: +``` + $ ./autogen.sh --prefix=/some_directory +``` +Then, regardless of how the tarball was made: +``` + $ make + $ make install +``` +You can build the examples and tests, and run the tests, like so: +``` + $ make check +``` + +## Building from git + +Building from git can be difficult so you should prefer building from +a release tarball unless you need to work on the libxml++ code itself. + +jhbuild can be a good help +- https://gitlab.gnome.org/GNOME/jhbuild +- https://wiki.gnome.org/Projects/Jhbuild +- https://gnome.pages.gitlab.gnome.org/jhbuild + +### Building from git with Meson + +Maintainer-mode is enabled by default when you build from a git clone. + +Don't call the builddir 'build'. There is a directory called 'build' with +files used by Autotools. +``` + $ meson setup --prefix /some_directory --libdir lib your_builddir . + $ cd your_builddir + $ ninja + $ ninja install +``` +You can run the tests like so: +``` + $ ninja test +``` +You can create a tarball like so: +``` + $ ninja dist +``` + +### Building from git with Autotools +``` + $ ./autogen.sh --prefix=/some_directory + $ make + $ make install +``` +You can build the examples and tests, and run the tests, like so: +``` + $ make check +``` +You can create a tarball like so: +``` + $ make distcheck +``` +or +``` + $ make dist +``` diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 00000000..189b364c --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,13 @@ +/compile +/compile-binding.am +/config.* +/depcomp +/dist-changelog.am +/doc-reference.am +/generate-binding.am +/install-sh +/libtool.m4 +/lt*.m4 +/ltmain.sh +/missing +/test-driver diff --git a/build/cxx_std.m4 b/build/cxx_std.m4 new file mode 100644 index 00000000..7977f9b7 --- /dev/null +++ b/build/cxx_std.m4 @@ -0,0 +1,52 @@ +## Copyright (C) 2015 The libxml++ development team +## +## This file is part of libxml++. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public +## License as published by the Free Software Foundation; either +## version 2.1 of the License, or (at your option) any later version. +## +## This library is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library. If not, see . + +## LIBXMLXX_CXX_HAS_EXCEPTION_PTR() +## +## Test whether std::exception_ptr, std::current_exception() and +## std::rethrow_exception() are defined. +## +## On success, #define LIBXMLXX_HAVE_EXCEPTION_PTR to 1. +## +AC_DEFUN([LIBXMLXX_CXX_HAS_EXCEPTION_PTR], +[ + AC_CACHE_CHECK( + [whether C++ library supports std::exception_ptr], + [libxmlxx_cv_cxx_has_exception_ptr], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ + #include + ]],[[ + try + { + throw "custom error"; + } + catch(...) + { + std::exception_ptr ep = std::current_exception(); + std::rethrow_exception(ep); + } + ]])], + [libxmlxx_cv_cxx_has_exception_ptr='yes'], + [libxmlxx_cv_cxx_has_exception_ptr='no'] + ) + ]) + + AS_IF([test "x${libxmlxx_cv_cxx_has_exception_ptr}" = 'xyes'], + [AC_DEFINE([LIBXMLXX_HAVE_EXCEPTION_PTR], [1], [Defined if the C++ library supports std::exception_ptr.])]) +]) diff --git a/configure.ac b/configure.ac index 6fce8806..1677fe1b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,51 +1,58 @@ -AC_INIT([libxml++], [2.39.2], - [https://bugzilla.gnome.org/enter_bug.cgi?product=libxml%2B%2B], - [libxml++], [http://libxmlplusplus.sourceforge.net/]) +## This file is part of libxml++. + +AC_INIT([libxml++], [5.4.0], + [https://github.com/libxmlplusplus/libxmlplusplus/issues], + [libxml++], [https://libxmlplusplus.github.io/libxmlplusplus/]) AC_PREREQ([2.59]) AC_CONFIG_SRCDIR([libxml++/libxml++.h]) -AC_CONFIG_AUX_DIR([macros]) -AC_CONFIG_MACRO_DIR([macros]) +AC_CONFIG_AUX_DIR([build]) +AC_CONFIG_MACRO_DIR([build]) AC_CONFIG_HEADERS([config.h libxml++config.h]) -AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2 no-define nostdinc subdir-objects]) -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES]) +AM_INIT_AUTOMAKE([1.9 -Wno-portability dist-bzip2 no-define nostdinc subdir-objects foreign]) +# Support silent build rules. +# Disable by either passing --disable-silent-rules to configure or passing V=1 to make. +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AM_MAINTAINER_MODE([disable]) AC_ARG_VAR([ACLOCAL_FLAGS], [aclocal flags, e.g. -I ]) -MM_PREREQ([0.9.8]) -MM_INIT_MODULE([libxml++-2.6]) +MM_PREREQ([0.9.10]) +MM_INIT_MODULE([libxml++-5.0]) -# Copy the mm-common .pl scripts into docs/, -# and use them from there, +# Tell mm-common-prepare to copy the mm-common .pl scripts +# and some other files into docs/, and use them from there, # so we can dist them to avoid a tarball-build dependency. MM_CONFIG_DOCTOOL_DIR([docs]) +# Library version (so version) [current:revision:age] # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html -AC_SUBST([LIBXMLXX_SO_VERSION], [2:7:0]) +AC_SUBST([LIBXMLXX_SO_VERSION], [1:0:0]) AC_PROG_CXX -MM_AX_CXX_COMPILE_STDCXX_11([noext],[mandatory]) +MM_AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) LT_PREREQ([2.2.6]) LT_INIT([dlopen win32-dll disable-static]) -AC_SUBST([LIBXMLXX_MODULES], ['libxml-2.0 >= 2.7.7 glibmm-2.4 >= 2.32.0']) +AC_SUBST([LIBXMLXX_MODULES], ['libxml-2.0 >= 2.7.7']) +AC_SUBST([LIBXML2_LIB_NO_PKGCONFIG], ['']) +AC_SUBST([MSVC_TOOLSET_VER], ['']) +AC_SUBST(DOXYGEN_HAVE_DOT, [YES]) +AM_SUBST_NOTMAKE(DOXYGEN_HAVE_DOT) PKG_CHECK_MODULES([LIBXMLXX], [$LIBXMLXX_MODULES]) AC_LANG([C++]) AC_CHECK_HEADERS([string list map], [], [AC_MSG_ERROR([required headers not found])]) +LIBXMLXX_CXX_HAS_EXCEPTION_PTR MM_ARG_ENABLE_DOCUMENTATION MM_ARG_WITH_TAGFILE_DOC([libstdc++.tag], [mm-common-libstdc++]) -MM_ARG_WITH_TAGFILE_DOC([libsigc++-2.0.tag], [sigc++-2.0]) -MM_ARG_WITH_TAGFILE_DOC([glibmm-2.4.tag], [glibmm-2.4]) # Evaluate the --enable-warnings=level option. MM_ARG_ENABLE_WARNINGS([LIBXMLXX_WXXFLAGS], [-Wall], - [-pedantic -Wall -Wextra -Wformat-security -Wshadow -Wno-long-long], - [G GLIBMM SIGCXX]) + [-pedantic -Wall -Wextra -Wformat-security -Wsuggest-override -Wshadow -Wno-long-long]) # Offer the ability to omit some API from the library. MM_ARG_DISABLE_DEPRECATED_API([LIBXMLXX]) @@ -56,20 +63,17 @@ AC_PATH_PROGS([DB2LATEX], [db2latex docbook2latex], [db2latex]) AC_ARG_VAR([DB2LATEX], [path to db2latex utility]) MM_CHECK_PERL() -# This is just defined to avoid breaking old code: -AC_DEFINE([LIBXMLCPP_EXCEPTIONS_ENABLED],[1], [This is always set. This is only for backwards compatibility.]) - AC_CONFIG_FILES([Makefile libxml++/Makefile examples/Makefile tests/Makefile docs/Makefile docs/reference/Doxyfile - MSVC_Net2010/libxml++/libxml++.rc - libxml++-2.6.pc]) + MSVC_NMake/libxml++/libxml++.rc + ${LIBXMLXX_MODULE_NAME}.pc:libxml++.pc.in]) # Copy the generated configuration headers into the MSVC project directories. -AC_CONFIG_COMMANDS([MSVC_Net2010/libxml++/libxml++config.h], - [cp -f libxml++config.h MSVC_Net2010/libxml++/libxml++config.h]) +AC_CONFIG_COMMANDS([MSVC_NMake/libxml++/libxml++config.h], + [cp -f libxml++config.h MSVC_NMake/libxml++/libxml++config.h]) AC_OUTPUT diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 00000000..57510a2b --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_site/ diff --git a/docs/Makefile.am b/docs/Makefile.am index 9458f002..8dfc7b29 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -19,10 +19,11 @@ book_name = $(LIBXMLXX_MODULE_NAME) doc_input = $(addprefix $(top_srcdir)/libxml++/,$(h_sources_public)) # Sets dist_noinst_DATA, DISTCLEANFILES and MAINTAINERCLEANFILES -include $(top_srcdir)/macros/doc-reference.am +include $(top_srcdir)/build/doc-reference.am -manual/libxml++.xml: manual/libxml++_without_code.xml manual/insert_example_code.pl - $(AM_V_GEN)$(PERL) -- manual/insert_example_code.pl ../examples $< >$@ +manual/libxml++.xml: ${top_srcdir}/docs/manual/libxml++_without_code.xml ${top_srcdir}/docs/manual/insert_example_code.pl + $(AM_V_at)$(MKDIR_P) manual + $(AM_V_GEN)$(PERL) -- ${top_srcdir}/docs/manual/insert_example_code.pl ${top_srcdir}/examples $< >$@ manualdir = $(docdir)/manual manual_htmldir = $(manualdir)/html diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..3f90fe29 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1 @@ +title: libxml++ diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 00000000..6025e935 --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,17 @@ +--- +--- + + + + libxml++ -- a C++ wrapper for the libxml2 XML parser library. + + + + + +
+

{{page.title}}

+ {{ content }} +
+ + diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 681c4552..00000000 --- a/docs/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - libxml++ - - - -
-

-libxml++

- -

Introduction

-

-libxml++ is a C++ wrapper for the libxml XML parser library. -

- -

License

-

Libxml++ is released under the LGPL version 2 or above

- -

Download

-

You can download libxml++ from here.

-

Required Libraries

- - -

Documentation

-

The short manual gives an overview of the libxml++ API. You can also browse online the reference documentation. -

- - -

Development

-

Libxml++ uses the GNOME git repository.

-

Bugs and patches are tracked in GNOME's bugzilla. Here is a list of open bugs. Add new bugs here.

-

Contact

-

Please use the libxmlplusplus-list mailing -list or bugzilla. Please do not just email the developers directly.

-

- -*SOURCEFORGE* -

- - diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..db26ce69 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,81 @@ +--- +layout: default +title: libxml++ +--- +## Introduction + +libxml++ is a C++ wrapper for the [libxml2](http://www.xmlsoft.org) XML parser library. + +## License + +Libxml++ is released under the [LGPL](https://www.gnu.org/licenses/lgpl.html) version 2 or above. + +## ABI Versions + +There are several ABI (Application Binary Interface) versions of libxml++. +They can be installed in parallel. + +- libxml++-2.6: Old ABI, not recommended for new applications. + Uses Glib::ustring from the glibmm-2.4 ABI. + +- libxml++-3.0: Uses Glib::ustring from the glibmm-2.4 ABI, + therefore has methods that handle UTF-8 characters rather than raw bytes. + +- libxml++-4.0: Uses Glib::ustring from the newer glibmm-2.68 ABI, + therefore has methods that handle UTF-8 characters rather than raw bytes. + +- libxml++-5.0: Does not depend on glibmm, is not as good at handling UTF-8 strings, + has fewer dependencies. + +The APIs of libxml++-3.0, libxml++-4.0 and libxml++-5.0 are very similar. +The only significant difference is that libxml++-5.0 uses xmlpp::ustring +instead of Glib::ustring. + +In a new application, choose between libxml++-4.0 with UTF-8 support and libxml++-5.0 +with fewer dependencies. Choose libxml++-3.0 only if you want UTF-8 support but +don't have access to the newer glibmm-2.68 ABI (glibmm version 2.68.0 or higher). + +## Download + +You can download libxml++ from [GitHub releases](https://github.com/libxmlplusplus/libxmlplusplus/releases/) +(since 2.42.0, 3.2.0, 4.0.0 and 5.0.0) +or the [GNOME download site](https://download.gnome.org/sources/libxml++/) +(until 2.42.3, 3.2.5, 4.2.0 and 5.4.0). + +## Required Libraries + +* [libxml2](http://www.xmlsoft.org/) +* libxml++-2.6 and libxml++-3.0: glibmm-2.4 +* libxml++-4.0: [glibmm-2.68](https://gnome.pages.gitlab.gnome.org/glibmm/) + +## Documentation + +### libxml++-5.0 + +The short [manual](manual/html/index.html) gives an overview of the libxml++ API. +You can also browse online the [reference documentation](reference/html/index.html). + +### Other ABI Versions + +The documentation of libxml++-2.6, libxml++-3.0 and libxml++-4.0 is not +available online. You can download a tarball from +[GitHub releases](https://github.com/libxmlplusplus/libxmlplusplus/releases/) +or the [GNOME download site](https://download.gnome.org/sources/libxml++/), +extract it, and view the documentation at *untracked/docs/*. + +## Development + +Libxml++ uses the GitHub [git repository](https://github.com/libxmlplusplus/libxmlplusplus). + +Bugs and patches are tracked in GitHub's [issue tracker](https://github.com/libxmlplusplus/libxmlplusplus/issues) +and [pull request tracker](https://github.com/libxmlplusplus/libxmlplusplus/pulls). + +## Discussion + +You can discuss libxml++ questions on GNOME's [Discourse](https://discourse.gnome.org) +instance, under the [Platform/Language bindings](https://discourse.gnome.org/c/platform/language-bindings) +category with a _cplusplus_ tag. + +There is an old mailing list, which is now closed for new posts. +There is an archive of messages [here](https://mail.gnome.org/archives/libxmlplusplus-list/). +Please do not email the developers directly. diff --git a/docs/manual/can_use_xmllint.xml b/docs/manual/can_use_xmllint.xml new file mode 100644 index 00000000..8ff1b0d4 --- /dev/null +++ b/docs/manual/can_use_xmllint.xml @@ -0,0 +1,15 @@ + + + +xmllint test + + +Introduction + + This is a short DocBook V5.0 document. It can be used for testing if the installed + version of xmllint or a similar program can validate a DocBook V5.0 document. + + + + diff --git a/docs/manual/insert_example_code.pl b/docs/manual/insert_example_code.pl index 85aef6b9..8d18f319 100755 --- a/docs/manual/insert_example_code.pl +++ b/docs/manual/insert_example_code.pl @@ -16,9 +16,9 @@ #Beginning of comment: # Look for - # Source Code + # Source Code - if(/Source Code<\/ulink><\/para>/) + if(/Source Code<\/link><\/para>/) { #List all the source files in that directory: my $directory = $examples_base . $1; diff --git a/docs/manual/insert_example_code.py b/docs/manual/insert_example_code.py new file mode 100755 index 00000000..e8985d71 --- /dev/null +++ b/docs/manual/insert_example_code.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 + +# argv[1] argv[2:-1] argv[-1] +# insert_example_code.py ... + +import os +import sys +import re +import glob +import shutil + +# Where to insert example code. +source_include_pattern = re.compile( + r'\s*Source Code') + +# First line not part of leading comment in a source code file. +# The comment typically consists of copyright and license text. +start_of_source_pattern = re.compile(r'[#\w]') + +def process_source_file(source_directory, source_basename, outfile): + source_filename = os.path.join(source_directory, source_basename) + with open(source_filename, mode='r', encoding='utf-8', errors='surrogateescape') as srcfile: + outfile.write('File: ' + source_basename + '\n') + outfile.write('\n\n') + +def insert_example_code(examples_base_dir, input_xml_files, output_xml_file): + if not isinstance(input_xml_files, list): + input_xml_files = [input_xml_files] + + # Assume that all files are UTF-8 encoded. + # If illegal UTF-8 bytes in the range 0x80..0xff are encountered, they are + # replaced by Unicode Private Use characters in the range 0xdc80..0xdcff + # and restored to their original values when the file is rewritten. + with open(output_xml_file, mode='w', encoding='utf-8', errors='surrogateescape') as outfile: + for input_xml_file in input_xml_files: + with open(input_xml_file, mode='r', encoding='utf-8', errors='surrogateescape') as infile: + for line in infile: + # Print the line. + outfile.write(line) + + # Look for + # Source Code + source_include_match = source_include_pattern.match(line) + if source_include_match: + # List all the source files in the examples directory. + source_directory = os.path.join(examples_base_dir, source_include_match.group(1)) + outfile.write('\n') + for source_filename in sorted(glob.glob(os.path.join(source_directory, '*.h'))) + \ + sorted(glob.glob(os.path.join(source_directory, '*.cc'))): + source_basename = os.path.basename(source_filename) + process_source_file(source_directory, source_basename, outfile) + outfile.write('\n') + return 0 + +# ----- Main ----- +if __name__ == '__main__': + if len(sys.argv) < 4: + print('Usage: ' + sys.argv[0] + ' ... ') + sys.exit(1) + + sys.exit(insert_example_code(sys.argv[1], sys.argv[2:-1], sys.argv[-1])) diff --git a/docs/manual/libxml++_without_code.xml b/docs/manual/libxml++_without_code.xml index bba9147c..7a921edf 100644 --- a/docs/manual/libxml++_without_code.xml +++ b/docs/manual/libxml++_without_code.xml @@ -1,16 +1,18 @@ - - + - + ]> - - - + + libxml++ - An XML Parser for C++ - Murray - Cumming + + Murray + Cumming +
murrayc@murrayc.com
@@ -19,11 +21,13 @@ This is an introduction to libxml2's C++ binding, with simple examples. -
- - libxml++ + + + + libxml++ + - libxml++ is a C++ API for the popular libxml2 XML parser, written in C. + libxml++ is a C++ API for the popular libxml2 XML parser, written in C. libxml2 is famous for its high performance and compliance to standard specifications, but its C API is quite difficult even for common tasks. @@ -32,59 +36,61 @@ Unlike some other C++ parsers, it does not try to avoid the advantages of standard C++ features such as namespaces, STL containers or runtime type identification, and it does not try to conform to standard API specifications meant for Java. Therefore libxml++ requires - a fairly modern C++ compiler such as g++ 4.9 or g++ 5. libxml++ 2.39.1 and later require - a C++11-compliant compiler. + a fairly modern C++ compiler such as g++ 8 or g++ 9. libxml++ 3.9.1 and later require + a C++17-compliant compiler.
- But libxml++ was created mainly to fill the need for an API-stable and ABI-stable C++ XML parser which could be used as a shared library dependency by C++ applications that are distributed widely in binary form. That means that installed applications will not break when new versions of libxml++ are installed on a user's computer. Gradual improvement of the libxml++ API is still possible via non-breaking API additions, and new independent versions of the ABI that can be installed in parallel with older versions. These are the general techniques and principles followed by the GNOME project, of which libxml++ is a part. + But libxml++ was created mainly to fill the need for an API-stable and ABI-stable C++ XML parser which could be used as a shared library dependency by C++ applications that are distributed widely in binary form. That means that installed applications will not break when new versions of libxml++ are installed on a user's computer. Gradual improvement of the libxml++ API is still possible via non-breaking API additions, and new independent versions of the ABI that can be installed in parallel with older versions. These are the general techniques and principles followed by the + GNOME project, of which libxml++ is a part. + +
+ Installation - - Installation - libxml++ is packaged by major Linux and *BSD distributions and can be installed from source on Linux and Windows, using any modern compiler, such as g++, SUN Forte, or MSVC++. - For instance, to install libxml++ and its documentation on debian, use apt-get or synaptic like so: + libxml++ is packaged by major Linux and *BSD distributions and can be installed from source on Linux and Windows, using any modern compiler, such as g++ or MSVC++. + For instance, to install libxml++ and its documentation on Debian, use apt-get or synaptic like so: - # apt-get install libxml++2.6-dev libxml++2.6-doc + # apt-get install libxml++5.0-dev libxml++5.0-doc - To check that you have the libxml++ development packages installed, and that your environment is working properly, try pkg-config libxml++-2.6 --modversion. - Links for downloading and more documentation can be found at libxmlplusplus.sourceforge.net. + To check that you have the libxml++ development packages installed, and that your environment is working properly, try pkg-config libxml++-5.0 --modversion. + Links for downloading and more documentation can be found at + libxmlplusplus.github.io/libxmlplusplus. libxml++ is licensed under the LGPL, which allows its use via dynamic linking in both open source and closed-source software. The underlying libxml2 library uses the even more generous MIT licence. - +
+ +
+ UTF-8 and xmlpp::ustring - - UTF-8 and Glib::ustring The libxml++ API takes, and gives, strings in the UTF-8 Unicode encoding, which can support all known languages and locales. This choice was made because, of the encodings that have this capability, UTF-8 is the most commonly accepted choice. UTF-8 is a multi-byte encoding, meaning that some characters use more than 1 byte. But for compatibility, old-fashioned 7-bit ASCII strings are unchanged when encoded as UTF-8, and UTF-8 strings do not contain null bytes which would cause old code to misjudge the number of bytes. For these reasons, you can store a UTF-8 string in a std::string object. However, the std::string API will operate on that string in terms of bytes, instead of characters. - Because Standard C++ has no string class that can fully handle UTF-8, libxml++ uses the Glib::ustring class from the glibmm library. Glib::ustring has almost exactly the same API as std::string, but methods such as length() and operator[] deal with whole UTF-8 characters rather than raw bytes. - There are implicit conversions between std::string and Glib::ustring, so you can use std::string wherever you see a Glib::ustring in the API, if you really don't care about any locale other than English. However, that is unlikely in today's connected world. - glibmm also provides useful API to convert between encodings and locales. - + The libxml++ API indicates when a string should be provided as UTF-8, or will be provided as UTF-8, by using the xmlpp::ustring type alias. However, this is really just a std::string, whose operator[] and size() consider bytes, not characters. +
+ +
+ Compilation and Linking - - Compilation and Linking To use libxml++ in your application, you must tell the compiler where to find the include headers and where to find the libxml++ library. libxml++ provides a pkg-config .pc file to make this easy. For instance, the following command will provide the necessary compiler options: - pkg-config libxml++-2.6 --cflags --libs + pkg-config libxml++-5.0 --cflags --libs When using autoconf and automake, this is even easier with the PKG_CHECK_MODULES macro in your configure.ac file. For instance: - PKG_CHECK_MODULES(SOMEAPP, libxml++-2.6 >= 2.38.0) + PKG_CHECK_MODULES(SOMEAPP, libxml++-5.0 >= 5.0.0) AC_SUBST(SOMEAPP_CFLAGS) AC_SUBST(SOMEAPP_LIBS) - +
+ - + + Parsers - - Parsers Like the underlying libxml2 library, libxml++ allows the use of 3 parsers, depending on your needs - the DOM, SAX, and TextReader parsers. The relative advantages and behaviour of these parsers will be explained here. - All of the parsers may parse XML documents directly from disk, a string, or a C++ std::istream. Although the libxml++ API uses only Glib::ustring, and therefore the UTF-8 encoding, libxml++ can parse documents in any encoding, converting to UTF-8 automatically. This conversion will not lose any information because UTF-8 can represent any locale. - Remember that white space is usually significant in XML documents, so the parsers might provide unexpected text nodes that contain only spaces and new lines. The parser does not know whether you care about these text nodes, but your application may choose to ignore them. - - - DOM Parser + All of the parsers may parse XML documents directly from disk, a string, or a C++ std::istream. Although the libxml++ API uses only xmlpp::ustring, indicating the UTF-8 encoding, libxml++ can parse documents in any encoding, converting to UTF-8 automatically. This conversion will not lose any information because UTF-8 can represent any locale. + Remember that white space is usually significant in XML documents, so the parsers might provide unexpected text nodes that contain only spaces and new lines. The parser does not know whether you care about these text nodes, but your application may choose to ignore them. + +
+ DOM Parser + The DOM (Document Object Model) parser parses the whole document at once and stores the structure in memory, available via DomParser::get_document(). With methods such as Document::get_root_node() and Node::get_children(), you may then navigate into the hierarchy of XML nodes without restriction, jumping forwards or backwards in the document based on the information that you encounter. Therefore the DOM parser uses a relatively large amount of memory. You should use C++ RTTI (via dynamic_cast<>) to identify the specific node type and to perform actions which are not possible with all node types. For instance, only Elements have attributes. Here is the inheritance hierarchy of node types: @@ -113,7 +119,6 @@ url="http://libxmlplusplus.sourceforge.net">libxmlplusplus.sourceforge.netxmlpp::XIncludeStart - @@ -126,48 +131,45 @@ url="http://libxmlplusplus.sourceforge.net">libxmlplusplus.sourceforge.netAlthough you may obtain pointers to the Nodes, these Nodes are always owned by their parent Node. In most cases that means that the Node will exist, and your pointer will be valid, as long as the Document instance exists. There are also several methods which can create new child Nodes. By using these, and one of the Document::write_*() methods, you can use libxml++ to build a new XML document. - -Example +
+Example + This example looks in the document for expected elements and then examines them. All these examples are included in the libxml++ source distribution. -Source Code - +Source Code +
+
+
+ SAX Parser - + The SAX (Simple API for XML) parser presents each node of the XML document in sequence. So when you process one node, you must have already stored information about any relevant previous nodes, and you have no information at that time about subsequent nodes. The SAX parser uses less memory than the DOM parser and it is a suitable abstraction for documents that can be processed sequentially rather than as a whole. + By using the parse_chunk() method instead of for instance parse_file(), you can even parse parts of the XML document before you have received the whole document. - - SAX Parser - The SAX (Simple API for XML) parser presents each node of the XML document in sequence. So when you process one node, you must have already stored information about any relevant previous nodes, and you have no information at that time about subsequent nodes. The SAX parser uses less memory than the DOM parser and it is a suitable abstraction for documents that can be processed sequentially rather than as a whole. + As shown in the example, you should derive your own class from SaxParser and override some of the virtual methods. These "handler" methods will be called while the document is parsed. - By using the parse_chunk() method instead of parse(), you can even parse parts of the XML document before you have received the whole document. +
+Example - As shown in the example, you should derive your own class from SaxParser and override some of the virtual methods. These "handler" methods will be called while the document is parsed. - - -Example This example shows how the handler methods are called during parsing. -Source Code - +Source Code +
+
-
+
+ TextReader Parser - - TextReader Parser Like the SAX parser, the TextReader parser is suitable for sequential parsing, but instead of implementing handlers for specific parts of the document, it allows you to detect the current node type, process the node accordingly, and skip forward in the document as much as necessary. Unlike the DOM parser, you may not move backwards in the XML document. And unlike the SAX parser, you must not waste time processing nodes that do not interest you. - All methods are on the single parser instance, but their result depends on the current context. For instance, use read() to move to the next node, and move_to_element() to navigate to child nodes. These methods will return false when no more nodes are available. Then use methods such as get_name() and get_value() to examine the elements and their attributes. - - -Example -This example examines each node in turn, then moves to the next node. -Source Code - + All methods are on the single parser instance, but their result depends on the current context. For instance, use read() to move to the next node, and move_to_element() to navigate to child nodes. These methods will return false when no more nodes are available. Then use methods such as get_name() and get_value() to examine the elements and their attributes. +
+Example - +This example examines each node in turn, then moves to the next node. +Source Code +
+
-
- diff --git a/docs/manual/meson.build b/docs/manual/meson.build new file mode 100644 index 00000000..1c69899d --- /dev/null +++ b/docs/manual/meson.build @@ -0,0 +1,117 @@ +# docs/manual + +# input: install_datadir, xmlxx_pcname, tutorial_custom_cmd_py, python3, +# build_documentation, book_name, xsltproc +# output: can_parse_and_validate, build_pdf_by_default, can_build_pdf, +# install_tutorialdir, build_manual_opt, build_manual + +build_manual_opt = get_option('build-manual') +build_manual = build_manual_opt and build_documentation + +xmllint = find_program('xmllint', required: false) +can_parse_and_validate = xmllint.found() +validate = get_option('validation') ? 'true' : 'false' + +dblatex = find_program('dblatex', required: false) +can_build_pdf = dblatex.found() or (xsltproc.found() and \ + find_program('fop', required: false).found()) +build_pdf_by_default = get_option('build-pdf') + +# Installation directories are relative to {prefix}. +install_tutorialdir = install_datadir / 'doc' / book_name / 'manual' + +if not build_manual + # The manual shall not be built or installed. + # Return to the calling meson.build file. + subdir_done() +endif + +# Check if xmllint can be used. +if xmllint.found() + can_parse_and_validate = run_command( + python3, tutorial_custom_cmd_py, 'xmllint', + validate, + meson.current_source_dir() / 'can_use_xmllint.xml', + meson.current_build_dir() / 'can_use_xmllint.stamp', + check: false, + ).returncode() == 0 + if not can_parse_and_validate + # The DocBook V5.0 package is called docbook5-xml in Ubuntu, + # docbook5-schemas in Fedora. It may have other names in other distros. + warning('Can\'t validate XML file.\n' + + 'xmllint does not support Relax NG schemas and DocBook V5.0.\n' + + 'DocBook V5.0 support may require docbook5-xml, docbook5-schemas or a similar package.' + ) + endif +endif + +doc_dist_dir = 'untracked' / 'docs' / 'manual' # Relative to MESON_DIST_ROOT + +# Create a DocBook XML file with the examples' source code included. +xml_manual_docbook = custom_target('libxml++.xml', + input: 'libxml++_without_code.xml', + output: 'libxml++.xml', + command: [ + python3, tutorial_custom_cmd_py, 'insert_example_code', + meson.current_source_dir(), + project_source_root / 'examples', + '@INPUT@', + '@OUTPUT@', + ], + build_by_default: true +) + +# Create an html version of the DocBook. +custom_target('manual_html', + input: xml_manual_docbook, + output: 'html', + command: [ + python3, tutorial_custom_cmd_py, 'html', + '@INPUT@', + '@OUTPUT@', + ], + build_by_default: true, + install: true, + install_dir: install_tutorialdir, + install_tag: 'doc', +) + +if can_parse_and_validate + # Parse and possibly validate the DocBook. + custom_target('manual_xmllint', + input: xml_manual_docbook, + output: 'manual_xmllint.stamp', + command: [ + python3, tutorial_custom_cmd_py, 'xmllint', + validate, + '@INPUT@', + '@OUTPUT@' + ], + build_by_default: true, + ) +endif + +if can_build_pdf + # Create a PDF file of the DocBook. + # Prefer dblatex, if both dblatex and fop are available. + custom_target('manual_pdf', + input: xml_manual_docbook, + output: 'libxml++.pdf', + command: [ + python3, tutorial_custom_cmd_py, + dblatex.found() ? 'dblatex' : 'fop', + '@INPUT@', + '@OUTPUT@' + ], + build_by_default: build_pdf_by_default, + ) +endif + +# Distribute built files. +meson.add_dist_script( + python3, tutorial_custom_cmd_py, 'dist_doc', + doc_dist_dir, + meson.current_build_dir(), + meson.current_build_dir() / 'libxml++.xml', + meson.current_build_dir() / 'libxml++.pdf', +) diff --git a/docs/reference/Doxyfile.in b/docs/reference/Doxyfile.in index 87fd6b58..e6ac8265 100644 --- a/docs/reference/Doxyfile.in +++ b/docs/reference/Doxyfile.in @@ -1,4 +1,4 @@ -# Doxyfile 1.8.9.1 +# Doxyfile 1.8.11 # @configure_input@ #--------------------------------------------------------------------------- @@ -34,7 +34,6 @@ SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 ALIASES = "newin{2}=\xrefitem since_\1_\2 \"Since @PACKAGE_NAME@ \1.\2\" \"New API in @PACKAGE_NAME@ \1.\2\"" \ "newin{3}=\xrefitem since_\1_\2_\3 \"Since @PACKAGE_NAME@ \1.\2.\3\" \"New API in @PACKAGE_NAME@ \1.\2.\3\"" -TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO @@ -95,7 +94,7 @@ CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- -QUIET = NO +QUIET = YES WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES @@ -147,7 +146,6 @@ VERBATIM_HEADERS = NO # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output @@ -163,7 +161,6 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -HTML_TIMESTAMP = YES HTML_DYNAMIC_SECTIONS = NO HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO @@ -194,7 +191,6 @@ ENUM_VALUES_PER_LINE = 1 TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -FORMULA_TRANSPARENT = YES USE_MATHJAX = NO MATHJAX_FORMAT = HTML-CSS MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest @@ -215,7 +211,7 @@ LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO -PAPER_TYPE = a4wide +PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = @@ -225,7 +221,6 @@ PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # Configuration options related to the RTF output @@ -236,7 +231,6 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = -RTF_SOURCE_CODE = NO #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -256,7 +250,6 @@ XML_PROGRAMLISTING = NO #--------------------------------------------------------------------------- GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -DOCBOOK_PROGRAMLISTING = NO #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- @@ -291,11 +284,7 @@ PREDEFINED = __cplusplus \ "G_GNUC_PURE=" \ "G_GNUC_WARN_UNUSED_RESULT=" \ "G_MODULE_EXPORT=" \ - GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED \ - GLIBMM_EXCEPTIONS_ENABLED \ - GLIBMM_PROPERTIES_ENABLED \ - GLIBMM_VFUNCS_ENABLED \ - "LIBXMLXX_API=" + "LIBXMLPP_API=" EXPAND_AS_DEFINED = LIBXMLXX_MAJOR_VERSION \ LIBXMLXX_MINOR_VERSION \ LIBXMLXX_MICRO_VERSION @@ -308,18 +297,13 @@ GENERATE_TAGFILE = "reference/@LIBXMLXX_MODULE_NAME@.tag" ALLEXTERNALS = NO EXTERNAL_GROUPS = NO EXTERNAL_PAGES = YES -PERL_PATH = @PERL@ #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -MSCGEN_PATH = DIA_PATH = HIDE_UNDOC_RELATIONS = NO -HAVE_DOT = YES +HAVE_DOT = @DOXYGEN_HAVE_DOT@ DOT_NUM_THREADS = 0 -DOT_FONTNAME = Sans -DOT_FONTSIZE = 10 DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = NO @@ -343,7 +327,6 @@ PLANTUML_JAR_PATH = PLANTUML_INCLUDE_PATH = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES DOT_CLEANUP = YES diff --git a/docs/reference/meson.build b/docs/reference/meson.build new file mode 100644 index 00000000..72c7077f --- /dev/null +++ b/docs/reference/meson.build @@ -0,0 +1,141 @@ +# docs/reference + +# Input: project_build_root, project_source_root, xmlxx_pcname, +# xmlxx_api_version, build_documentation, source_h_files, +# install_datadir, python3, doc_reference_py, dot +# Output: install_docdir, install_devhelpdir, book_name, +# if build_documentation: tag_file + +# There are no built source files in libxml++-5.0. + +tag_file_modules = [ + 'mm-common-libstdc++', +] +doxygen_tagfiles = '' +doxygen_tag_targets = [] +docinstall_flags = [] +foreach module : tag_file_modules + depmod = dependency(module, required: false) + if depmod.found() + doxytagfile = depmod.get_variable('doxytagfile', default_value: '') + if doxytagfile != '' + if depmod.type_name() == 'internal' + # Subprojects must build their tag files before doxygen is called. + if module.startswith('mm-common') + doxygen_tag_targets += subproject('mm-common').get_variable('global_tag_file_target') + else + doxygen_tag_targets += subproject(module).get_variable('global_tag_file_target') + endif + endif + htmlrefpub = depmod.get_variable('htmlrefpub', default_value: '') + htmlrefdir = depmod.get_variable('htmlrefdir', default_value: '') + if htmlrefpub == '' + htmlrefpub = htmlrefdir + elif htmlrefdir == '' + htmlrefdir = htmlrefpub + endif + doxygen_tagfiles += ' "' + doxytagfile + '=' + htmlrefpub + '"' + + # Doxygen <= 1.8.15 + docinstall_flags += ['-l', doxytagfile.split('/')[-1] + '@' + htmlrefdir] + if htmlrefpub != htmlrefdir + # Doxygen >= 1.8.16 + docinstall_flags += ['-l', 's@' + htmlrefpub + '@' + htmlrefdir] + endif + endif + endif +endforeach + +book_name = xmlxx_pcname +book_title = meson.project_name() + ' Reference Manual' + +# Configuration data for Doxyfile. +doc_conf_data = configuration_data() +doc_conf_data.set('configure_input', + 'docs/reference/Doxyfile. Generated from Doxyfile.in by meson.configure_file().') +doc_conf_data.set('PACKAGE_NAME', meson.project_name()) +doc_conf_data.set('PACKAGE_VERSION', meson.project_version()) +doc_conf_data.set('abs_top_builddir', project_build_root) +doc_conf_data.set('abs_top_srcdir', project_source_root) +doc_conf_data.set('LIBXMLXX_MODULE_NAME', book_name) +doc_conf_data.set('DOXYGEN_TAGFILES', doxygen_tagfiles) +doc_conf_data.set('DOXYGEN_HAVE_DOT', dot.found() ? 'YES' : 'NO') + +doxyfile = configure_file( + input: 'Doxyfile.in', + output: '@BASENAME@', + configuration: doc_conf_data, +) + +# Installation directories relative to {prefix}. +install_docdir = install_datadir / 'doc' / book_name +install_reference_docdir = install_docdir / 'reference' +install_devhelpdir = install_datadir / 'devhelp' / 'books' / book_name + +if not build_documentation + # Documentation shall not be built or installed. + # Return to the calling meson.build file. + subdir_done() +endif + +# Input .h files to Doxygen. +src_h_files = [] +foreach file : source_h_files + src_h_files += project_source_root / 'libxml++' / file +endforeach +src_h_files += project_source_root / 'libxml++' / 'libxml++.h' + +doctool_dir = project_source_root / 'untracked' / 'docs' # MMDOCTOOLDIR +doctool_dist_dir = 'untracked' / 'docs' # Relative to MESON_DIST_ROOT + +tag_file = custom_target('html_and_tag', + input: src_h_files, + output: book_name + '.tag', + command: [ + python3, doc_reference_py, 'doxygen', + doctool_dir, + '@OUTPUT@', + '@INPUT@', + ], + depend_files: doxyfile, + depends: doxygen_tag_targets, + build_by_default: build_documentation, + install: true, + install_dir: install_reference_docdir, + install_tag: 'doc', +) + +devhelp_file = custom_target('devhelp', + input: tag_file, + output: book_name + '.devhelp2', + command: [ + python3, doc_reference_py, 'devhelp', + doctool_dir, + '@INPUT@', + '@OUTPUT@', + book_name, + book_title, + ], + build_by_default: build_documentation, +) + +# Install Devhelp file and html files. +meson.add_install_script( + python3, doc_reference_py, 'install_doc', + doctool_dir, + devhelp_file.full_path(), + install_devhelpdir, + install_reference_docdir / 'html', + docinstall_flags, + install_tag: 'doc', +) + +# Distribute built files and files copied by mm-common-get. +meson.add_dist_script( + python3, doc_reference_py, 'dist_doc', + doctool_dir, + doctool_dist_dir, + meson.current_build_dir(), + tag_file.full_path(), + devhelp_file.full_path(), +) diff --git a/docs/style.css b/docs/style.css new file mode 100644 index 00000000..ebb5b16f --- /dev/null +++ b/docs/style.css @@ -0,0 +1,4 @@ +body { + background-color: #F7F7F7; + font-family: Verdana, Arial, Helvetica, sans-serif; +} diff --git a/examples/Makefile.am b/examples/Makefile.am index f73e2850..6fa20eab 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -58,14 +58,12 @@ check_SCRIPTS = \ TESTS = $(check_SCRIPTS) -xmlpp_test_util = testutilities.h testutilities.cc - dom_build_dom_build_SOURCES = \ dom_build/main.cc dom_parse_entities_dom_parse_entities_SOURCES = \ - dom_parse_entities/main.cc $(xmlpp_test_util) + dom_parse_entities/main.cc dom_parser_dom_parser_SOURCES = \ - dom_parser/main.cc $(xmlpp_test_util) + dom_parser/main.cc dom_parser_raw_dom_parser_raw_SOURCES = \ dom_parser_raw/main.cc dom_read_write_dom_read_write_SOURCES = \ @@ -124,8 +122,8 @@ dist_noinst_DATA = \ dom_update_namespace/example1.xml \ dom_update_namespace/example2.xml \ dom_xinclude/example.xml \ - dom_xinclude/include1.txt \ - dom_xinclude/include2.xml \ + dom_xinclude/xinclude/include1.txt \ + dom_xinclude/xinclude/include2.xml \ dom_xpath/example.xml \ dtdvalidation/example.dtd \ import_node/example1.xml \ @@ -153,18 +151,18 @@ dist_noinst_DATA = \ # Here it's necessary to specify parameters when the input file and the output # file are located in different directories. dom_read_write/make_check.sh: Makefile - echo '# Generated and used by "make check"' >$@ - echo 'dom_read_write/dom_read_write "$(srcdir)/dom_read_write/example.xml" dom_read_write/example_output.xml >/dev/null' >>$@ - chmod +x $@ + $(AM_V_GEN)echo '# Generated and used by "make check"' >$@ + $(AM_V_at)echo 'dom_read_write/dom_read_write "$(srcdir)/dom_read_write/example.xml" dom_read_write/example_output.xml >/dev/null' >>$@ + $(AM_V_at)chmod +x $@ script_template = cd "$(srcdir)/" && "$(abs_builddir)//" >/dev/null standard_scripts = $(filter-out dom_read_write/make_check.sh,$(check_SCRIPTS)) # All other script files are generated like so: $(standard_scripts): Makefile - echo '# Generated and used by "make check"' >$@ - echo '$(subst ,$(subst /make_check.sh,,$@),$(script_template))' >>$@ - chmod +x $@ + $(AM_V_GEN)echo '# Generated and used by "make check"' >$@ + $(AM_V_at)echo '$(subst ,$(subst /make_check.sh,,$@),$(script_template))' >>$@ + $(AM_V_at)chmod +x $@ CLEANFILES = \ dom_read_write/example_output.xml \ diff --git a/examples/dom_build/main.cc b/examples/dom_build/main.cc index c1409bd6..2fd160e9 100644 --- a/examples/dom_build/main.cc +++ b/examples/dom_build/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,61 +13,52 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #include -#include +#include int main(int /* argc */, char** /* argv */) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - try { xmlpp::Document document; document.set_internal_subset("example_xml_doc", "", "example_xml_doc.dtd"); - document.set_entity_declaration("example1", xmlpp::XML_INTERNAL_GENERAL_ENTITY, + document.set_entity_declaration("example1", xmlpp::XmlEntityType::INTERNAL_GENERAL, "", "example_xml_doc.dtd", "Entity content"); document.add_processing_instruction("application1", "This is an example document"); document.add_comment("First comment"); //foo is the default namespace prefix. auto nodeRoot = document.create_root_node("exampleroot", "http://foo", "foo"); //Declares the namespace and uses its prefix for this node - nodeRoot->set_namespace_declaration("http://foobar", "foobar"); //Also associate this prefix with this namespace: + nodeRoot->set_namespace_declaration("http://foobar", "foobar"); //Also associate this prefix with this namespace: - nodeRoot->set_child_text("\n"); - auto nodeChild = nodeRoot->add_child("examplechild"); + nodeRoot->set_first_child_text("\n"); + auto nodeChild = nodeRoot->add_child_element("examplechild"); //Associate prefix with namespace: - nodeChild->set_namespace_declaration("http://bar", "bar"); - + nodeChild->set_namespace_declaration("http://bar", "bar"); + nodeChild->set_namespace("bar"); //So it will be bar::examplechild. nodeChild->set_attribute("id", "1", "foo"); //foo is the namespace prefix. You could also just use a name of foo:id". - nodeChild->set_child_text("\nSome content\n"); + nodeChild->set_first_child_text("\nSome content\n"); nodeChild->add_child_comment("Some comments"); nodeChild->add_child_entity_reference("example1"); nodeChild->add_child_entity_reference("#x20ac"); // € nodeChild->add_child_text("\n"); nodeChild->add_child_processing_instruction("application1", "This is an example node"); nodeChild->add_child_text("\n"); - nodeChild->add_child("child_of_child", "bar"); + nodeChild->add_child_element("child_of_child", "bar"); - nodeChild = nodeRoot->add_child("examplechild", "foobar"); //foobar is the namespace prefix + nodeChild = nodeRoot->add_child_element("examplechild", "foobar"); //foobar is the namespace prefix nodeChild->set_attribute("id", "2", "foobar"); //foobar is the namespace prefix. auto whole = document.write_to_string(); std::cout << "XML built at runtime: " << std::endl << whole << std::endl; - std::cout << "namespace of root node: " << nodeRoot->get_namespace_uri() << std::endl; + std::cout << "namespace of root node: " << nodeRoot->get_namespace_uri2().value_or("{[(no URI)]}") << std::endl; } catch(const std::exception& ex) { @@ -79,4 +68,3 @@ main(int /* argc */, char** /* argv */) return EXIT_SUCCESS; } - diff --git a/examples/dom_parse_entities/example.xml b/examples/dom_parse_entities/example.xml index 93d4a4c9..cb949986 100644 --- a/examples/dom_parse_entities/example.xml +++ b/examples/dom_parse_entities/example.xml @@ -1,7 +1,7 @@ - + diff --git a/examples/dom_parse_entities/main.cc b/examples/dom_parse_entities/main.cc index 1b220243..f3295cd2 100644 --- a/examples/dom_parse_entities/main.cc +++ b/examples/dom_parse_entities/main.cc @@ -13,23 +13,23 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "../testutilities.h" #include #include #include #include +std::ostream& operator<<(std::ostream& o, const std::optional& s) +{ + o << s.value_or("{[(no value)]}"); + return o; +} + void print_node(const xmlpp::Node* node, bool substitute_entities, unsigned int indentation = 0) -{ - const Glib::ustring indent(indentation, ' '); +{ + const std::string indent(indentation, ' '); std::cout << std::endl; //Separate nodes by an empty line. if (substitute_entities) @@ -38,7 +38,7 @@ void print_node(const xmlpp::Node* node, bool substitute_entities, unsigned int const auto nodeText = dynamic_cast(node); if (nodeText && !nodeText->is_white_space()) { - std::cout << indent << "text = " << CatchConvertError(nodeText->get_content()) << std::endl; + std::cout << indent << "text = " << nodeText->get_content2() << std::endl; } } else @@ -47,9 +47,9 @@ void print_node(const xmlpp::Node* node, bool substitute_entities, unsigned int const auto nodeEntityReference = dynamic_cast(node); if (nodeEntityReference) { - std::cout << indent << "entity reference name = " << CatchConvertError(nodeEntityReference->get_name()) << std::endl; - std::cout << indent << " resolved text = " << CatchConvertError(nodeEntityReference->get_resolved_text()) << std::endl; - std::cout << indent << " original text = " << CatchConvertError(nodeEntityReference->get_original_text()) << std::endl; + std::cout << indent << "entity reference name = " << nodeEntityReference->get_name2() << std::endl; + std::cout << indent << " resolved text = " << nodeEntityReference->get_resolved_text2() << std::endl; + std::cout << indent << " original text = " << nodeEntityReference->get_original_text2() << std::endl; } } // end if (substitute_entities) @@ -58,7 +58,7 @@ void print_node(const xmlpp::Node* node, bool substitute_entities, unsigned int { //Recurse through child nodes: for(const auto& child : node->get_children()) - { + { print_node(child, substitute_entities, indentation + 2); //recursive } } @@ -66,16 +66,12 @@ void print_node(const xmlpp::Node* node, bool substitute_entities, unsigned int int main(int argc, char* argv[]) { - // Set the global C++ locale to the user-specified locale. Then we can - // hopefully use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if(argc > 1 ) filepath = argv[1]; //Allow the user to specify a different XML file to parse. else filepath = "example.xml"; - + // Parse first without, then with, entity substitution. int return_code = EXIT_SUCCESS; bool substitute_entities = false; diff --git a/examples/dom_parser/main.cc b/examples/dom_parser/main.cc index 8e9371eb..85dd5b7b 100644 --- a/examples/dom_parser/main.cc +++ b/examples/dom_parser/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,61 +13,61 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "../testutilities.h" #include #include #include +std::ostream& operator<<(std::ostream& o, const std::optional& s) +{ + o << s.value_or("{[(no value)]}"); + return o; +} + void print_node(const xmlpp::Node* node, unsigned int indentation = 0) { - const Glib::ustring indent(indentation, ' '); + const std::string indent(indentation, ' '); std::cout << std::endl; //Separate nodes by an empty line. - + const auto nodeContent = dynamic_cast(node); const auto nodeText = dynamic_cast(node); const auto nodeComment = dynamic_cast(node); if(nodeText && nodeText->is_white_space()) //Let's ignore the indenting - you don't always want to do this. return; - - const auto nodename = node->get_name(); - if(!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text". + const auto nodename = node->get_name2(); + + if(!nodeText && !nodeComment && nodename) //Let's not say "name: text". { - const auto namespace_prefix = node->get_namespace_prefix(); + const auto namespace_prefix = node->get_namespace_prefix2(); std::cout << indent << "Node name = "; - if(!namespace_prefix.empty()) - std::cout << CatchConvertError(namespace_prefix) << ":"; - std::cout << CatchConvertError(nodename) << std::endl; + if(namespace_prefix) + std::cout << namespace_prefix << ":"; + std::cout << nodename << std::endl; } else if(nodeText) //Let's say when it's text. - e.g. let's say what that white space is. { std::cout << indent << "Text Node" << std::endl; } - //Treat the various node types differently: + //Treat the various node types differently: if(nodeText) { - std::cout << indent << "text = \"" << CatchConvertError(nodeText->get_content()) << "\"" << std::endl; + std::cout << indent << "text = \"" << nodeText->get_content2() << "\"" << std::endl; } else if(nodeComment) { - std::cout << indent << "comment = " << CatchConvertError(nodeComment->get_content()) << std::endl; + std::cout << indent << "comment = " << nodeComment->get_content2() << std::endl; } else if(nodeContent) { - std::cout << indent << "content = " << CatchConvertError(nodeContent->get_content()) << std::endl; + std::cout << indent << "content = " << nodeContent->get_content2() << std::endl; } - else if(const xmlpp::Element* nodeElement = dynamic_cast(node)) + else if(auto nodeElement = dynamic_cast(node)) { //A normal Element node: @@ -77,17 +75,15 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) std::cout << indent << " line = " << node->get_line() << std::endl; //Print attributes: - const auto attributes = nodeElement->get_attributes(); - for(xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) + for (const auto& attribute : nodeElement->get_attributes()) { - const auto attribute = *iter; - const auto namespace_prefix = attribute->get_namespace_prefix(); + const auto namespace_prefix = attribute->get_namespace_prefix2(); std::cout << indent << " Attribute "; - if(!namespace_prefix.empty()) - std::cout << CatchConvertError(namespace_prefix) << ":"; - std::cout << CatchConvertError(attribute->get_name()) << " = " - << CatchConvertError(attribute->get_value()) << std::endl; + if(namespace_prefix) + std::cout << namespace_prefix << ":"; + std::cout << attribute->get_name2() << " = " + << attribute->get_value2() << std::endl; } const auto attribute = nodeElement->get_attribute("title"); @@ -98,14 +94,13 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) std::cout << "AttributeNode "; else if (dynamic_cast(attribute)) std::cout << "AttributeDeclaration "; - std::cout << "title = " << CatchConvertError(attribute->get_value()) << std::endl; + std::cout << "title = " << attribute->get_value2() << std::endl; } } - + if(!nodeContent) { //Recurse through child nodes: - auto list = node->get_children(); for(const auto& child : node->get_children()) { print_node(child, indentation + 2); //recursive @@ -115,10 +110,6 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) int main(int argc, char* argv[]) { - // Set the global C++ locale to the user-specified locale. Then we can - // hopefully use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - bool validate = false; bool set_throw_messages = false; bool throw_messages = false; @@ -163,7 +154,7 @@ int main(int argc, char* argv[]) filepath = argv[argi]; //Allow the user to specify a different XML file to parse. else filepath = "example.xml"; - + try { xmlpp::DomParser parser; @@ -190,4 +181,3 @@ int main(int argc, char* argv[]) return EXIT_SUCCESS; } - diff --git a/examples/dom_parser_raw/main.cc b/examples/dom_parser_raw/main.cc index 5051784c..3d1fc38d 100644 --- a/examples/dom_parser_raw/main.cc +++ b/examples/dom_parser_raw/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,22 +13,20 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include -#include +#include #include -#include -#include +#include void print_node(const xmlpp::Node* node, unsigned int indentation = 0) { std::cout << std::endl; //Separate nodes by an empty line. - - std::cout << "Node name = " << node->get_name() << std::endl; + + std::cout << "Node name = " << node->get_name2().value_or("{[(no name)]}") << std::endl; //Recurse through child nodes: for(const auto& child : node->get_children()) @@ -59,46 +55,35 @@ std::string read_from_disk(const std::string& filepath) int main(int argc, char* argv[]) { - // Set the global C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if(argc > 1 ) filepath = argv[1]; //Allow the user to specify a different XML file to parse. else filepath = "example.xml"; - + try { xmlpp::DomParser parser; parser.set_validate(); parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically. - + auto contents = read_from_disk(filepath); std::string contents_ucs2; - try - { - contents_ucs2 = Glib::convert(contents, "UCS-2", "UTF-8"); - } - catch(const Glib::Error& ex) - { - std::cerr << "Glib::convert failed: " << ex.what() << std::endl; - } - - parser.parse_memory_raw((const unsigned char*)contents_ucs2.c_str(), contents_ucs2.size()); + // TODO: Convert to UCS2 (previously we used Glib::convert()) and pass that to parse_memory_raw(). + // //Look at the first few bytes, to see whether it really looks like UCS2. //Because UCS2 uses 2 bytes, we would expect every second byte to be zero for our simple example: - std::cout << "First 10 bytes of the UCS-2 data:" << std::endl; - for(std::string::size_type i = 0; (i < 10) && (i < contents_ucs2.size()); ++i) - { - std::cout << std::hex << (int)contents_ucs2[i] << ", "; - } - std::cout << std::endl; - + // std::cout << "First 10 bytes of the UCS-2 data:" << std::endl; + // for(std::string::size_type i = 0; (i < 10) && (i < contents_ucs2.size()); ++i) + // { + // std::cout << std::hex << (int)contents_ucs2[i] << ", "; + // } + // std::cout << std::endl; + + parser.parse_memory_raw((const unsigned char*)contents.c_str(), contents.size()); if(parser) { //Walk the tree: diff --git a/examples/dom_read_write/main.cc b/examples/dom_read_write/main.cc index 4948af04..3d9a115a 100644 --- a/examples/dom_read_write/main.cc +++ b/examples/dom_read_write/main.cc @@ -15,25 +15,20 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif -#include +#include #include -#include +#include int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - //Parse command-line arguments: std::string filepath_in; std::string filepath_out; diff --git a/examples/dom_update_namespace/main.cc b/examples/dom_update_namespace/main.cc index 9a733c25..8d1eec07 100644 --- a/examples/dom_update_namespace/main.cc +++ b/examples/dom_update_namespace/main.cc @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -32,18 +33,18 @@ class Tests protected: template - void assert_equal(const RefType& reference, const ValueType& value, const std::string& msg); + static void assert_equal(const RefType& reference, const ValueType& value, const std::string& msg); template - void assert_not_equal(const RefType& reference, const ValueType& value, const std::string& msg); + static void assert_not_equal(const RefType& reference, const ValueType& value, const std::string& msg); template - void fail(const RefType& reference, const ValueType& value, const std::string& msg); + static void fail(const RefType& reference, const ValueType& value, const std::string& msg); }; class fail_exception : public std::exception { public: - fail_exception(const std::string& msg) : msg_(msg) {} + explicit fail_exception(const std::string& msg) : msg_(msg) {} ~fail_exception() noexcept override {} const char* what() const noexcept override { return msg_.c_str(); } @@ -100,10 +101,10 @@ void TestNamespace::test_create_new_node_with_default_namespace() "Input file shouldn't have any child in alternate default namespace"); // Add child nodes in default namespace and check document again - auto child = root_->add_child("child"); + auto child = root_->add_child_element("child"); child->set_namespace_declaration(nsmap_["ns1"], ""); root_->add_child_text("\n"); - root_->add_child_with_new_ns("child", nsmap_["ns1"]); + root_->add_child_element_with_new_ns("child", nsmap_["ns1"]); root_->add_child_text("\n"); std::cout << " File " << filename << " after modification" << std::endl @@ -128,12 +129,12 @@ void TestNamespace::test_create_new_node_using_existing_namespace_prefix() "Input file shouldn't have any child in child namespace"); // Add child nodes with specific namespace and check document again - auto child = root_->add_child("child", "ns0"); + auto child = root_->add_child_element("child", "ns0"); child->set_namespace_declaration(nsmap_["ns1"], ""); root_->add_child_text("\n"); - root_->add_child_with_new_ns("child", nsmap_["ns1"]); + root_->add_child_element_with_new_ns("child", nsmap_["ns1"]); root_->add_child_text("\n"); - root_->add_child_with_new_ns("child", nsmap_["ns1"], "ns3"); + root_->add_child_element_with_new_ns("child", nsmap_["ns1"], "ns3"); root_->add_child_text("\n"); std::cout << " File " << filename << " after modification" << std::endl @@ -176,10 +177,6 @@ void Tests::fail(const RefType& reference, const ValueType& value, const std::st int main(int /* argc */, char** /* argv */) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - TestNamespace tests; try diff --git a/examples/dom_xinclude/example.xml b/examples/dom_xinclude/example.xml index e99a4a4e..b4d8bd18 100644 --- a/examples/dom_xinclude/example.xml +++ b/examples/dom_xinclude/example.xml @@ -1,7 +1,7 @@ -

- Did not find include1.txt. +

+ Did not find xinclude/include1.txt.

- +
diff --git a/examples/dom_xinclude/include1.txt b/examples/dom_xinclude/include1.txt deleted file mode 100644 index 6683a84a..00000000 --- a/examples/dom_xinclude/include1.txt +++ /dev/null @@ -1 +0,0 @@ -This is the contents of file include1.txt. \ No newline at end of file diff --git a/examples/dom_xinclude/main.cc b/examples/dom_xinclude/main.cc index 00312874..f42fc7a4 100644 --- a/examples/dom_xinclude/main.cc +++ b/examples/dom_xinclude/main.cc @@ -16,17 +16,19 @@ * License along with this library. If not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #include -#include +#include + +std::ostream& operator<<(std::ostream& o, const std::optional& s) +{ + o << s.value_or("{[(no value)]}"); + return o; +} void print_node(const xmlpp::Node* node, unsigned int indentation = 0) { - const Glib::ustring indent(indentation, ' '); + const std::string indent(indentation, ' '); const auto nodeContent = dynamic_cast(node); const auto nodeText = dynamic_cast(node); @@ -36,14 +38,14 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) if (nodeText && nodeText->is_white_space()) return; - const auto nodename = node->get_name(); + const auto nodename = node->get_name2(); - if (!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text". + if (!nodeText && !nodeComment && nodename) //Let's not say "name: text". { - const auto namespace_prefix = node->get_namespace_prefix(); + const auto namespace_prefix = node->get_namespace_prefix2(); std::cout << indent << "Node name = "; - if (!namespace_prefix.empty()) + if (namespace_prefix) std::cout << namespace_prefix << ":"; std::cout << nodename << std::endl; } @@ -55,38 +57,36 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) //Treat the various node types differently: if (nodeText) { - std::cout << indent << "text = \"" << nodeText->get_content() << "\"" << std::endl; + std::cout << indent << "text = \"" << nodeText->get_content2() << "\"" << std::endl; } else if (nodeComment) { - std::cout << indent << "comment = " << nodeComment->get_content() << std::endl; + std::cout << indent << "comment = " << nodeComment->get_content2() << std::endl; } else if (nodeContent) { - std::cout << indent << "content = " << nodeContent->get_content() << std::endl; + std::cout << indent << "content = " << nodeContent->get_content2() << std::endl; } - else if (const xmlpp::Element* nodeElement = dynamic_cast(node)) + else if (auto nodeElement = dynamic_cast(node)) { //A normal Element node: std::cout << indent << " Element line = " << node->get_line() << std::endl; //Print attributes: - const auto attributes = nodeElement->get_attributes(); - for (xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) + for (const auto& attribute : nodeElement->get_attributes()) { - const auto attribute = *iter; - const auto namespace_prefix = attribute->get_namespace_prefix(); + const auto namespace_prefix = attribute->get_namespace_prefix2(); std::cout << indent << " Attribute "; - if (!namespace_prefix.empty()) + if (namespace_prefix) std::cout << namespace_prefix << ":"; - std::cout << attribute->get_name() << " = " << attribute->get_value() << std::endl; + std::cout << attribute->get_name2() << " = " << attribute->get_value2() << std::endl; } const auto attribute = nodeElement->get_attribute("title"); if (attribute) { - std::cout << indent << "title = " << attribute->get_value() << std::endl; + std::cout << indent << "title = " << attribute->get_value2() << std::endl; } } else if (dynamic_cast(node)) @@ -110,15 +110,12 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0) int main(int argc, char* argv[]) { - // Set the global C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - bool validate = false; bool set_throw_messages = false; bool throw_messages = false; bool substitute_entities = true; bool generate_xinclude_nodes = true; + bool fixup_base_uris = true; int argi = 1; while (argc > argi && *argv[argi] == '-') // option @@ -142,13 +139,17 @@ int main(int argc, char* argv[]) case 'X': generate_xinclude_nodes = false; break; + case 'B': + fixup_base_uris = false; + break; default: - std::cout << "Usage: " << argv[0] << " [-v] [-t] [-e] [-x] [filename]" << std::endl + std::cout << "Usage: " << argv[0] << " [options]... [filename]" << std::endl << " -v Validate" << std::endl << " -t Throw messages in an exception" << std::endl << " -e Write messages to stderr" << std::endl << " -E Do not substitute entities" << std::endl - << " -X Do not generate XInclude nodes" << std::endl; + << " -X Do not generate XInclude nodes" << std::endl + << " -B Do not fix up base URIs" << std::endl; return EXIT_FAILURE; } argi++; @@ -158,12 +159,11 @@ int main(int argc, char* argv[]) filepath = argv[argi]; //Allow the user to specify a different XML file to parse. else filepath = "example.xml"; - + try { xmlpp::DomParser parser; - if (validate) - parser.set_validate(); + parser.set_validate(validate); if (set_throw_messages) parser.set_throw_messages(throw_messages); //We can have the text resolved/unescaped automatically. @@ -176,14 +176,31 @@ int main(int argc, char* argv[]) print_node(pNode); std::cout << std::endl << ">>>>> Number of XInclude substitutions: " - << parser.get_document()->process_xinclude(generate_xinclude_nodes) + << parser.get_document()->process_xinclude( + generate_xinclude_nodes, fixup_base_uris) + << std::endl << std::endl; + + std::cout << ">>>>> After XInclude processing with xmlpp::Document::process_xinclude(): " << std::endl << std::endl; pNode = parser.get_document()->get_root_node(); print_node(pNode); + // xmlpp::Document::write_to_string() does not write XIncludeStart and + // XIncludeEnd nodes. + const auto whole = parser.get_document()->write_to_string(); + std::cout << std::endl << whole << std::endl; + } + + parser.set_xinclude_options(true, generate_xinclude_nodes, fixup_base_uris); + parser.parse_file(filepath); + if (parser) + { + std::cout << ">>>>> After XInclude processing with xmlpp::DomParser::parse_file(): " + << std::endl << std::endl; + print_node(parser.get_document()->get_root_node()); + const auto whole = parser.get_document()->write_to_string(); - std::cout << std::endl << ">>>>> XML after XInclude processing: " << std::endl - << whole << std::endl; + std::cout << std::endl << whole << std::endl; } } catch (const std::exception& ex) diff --git a/examples/dom_xinclude/xinclude/include1.txt b/examples/dom_xinclude/xinclude/include1.txt new file mode 100644 index 00000000..8484d7c3 --- /dev/null +++ b/examples/dom_xinclude/xinclude/include1.txt @@ -0,0 +1 @@ +This is the contents of file xinclude/include1.txt. diff --git a/examples/dom_xinclude/include2.xml b/examples/dom_xinclude/xinclude/include2.xml similarity index 53% rename from examples/dom_xinclude/include2.xml rename to examples/dom_xinclude/xinclude/include2.xml index 19b2c9df..aaf8db1a 100644 --- a/examples/dom_xinclude/include2.xml +++ b/examples/dom_xinclude/xinclude/include2.xml @@ -1,4 +1,4 @@ -

This is the contents of file include2.xml.

+

This is the contents of file xinclude/include2.xml.

diff --git a/examples/dom_xpath/main.cc b/examples/dom_xpath/main.cc index 96bf6638..1df4884a 100644 --- a/examples/dom_xpath/main.cc +++ b/examples/dom_xpath/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,34 +13,65 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include +#include #include +#include + +std::ostream& operator<<(std::ostream& o, const std::optional& s) +{ + o << s.value_or("{[(no value)]}"); + return o; +} -Glib::ustring result_type_to_ustring(xmlpp::XPathResultType result_type) +std::string result_type_to_ustring(xmlpp::XPathResultType result_type) { switch (result_type) { - case xmlpp::XPATH_RESULT_NODESET: return "nodeset"; - case xmlpp::XPATH_RESULT_BOOLEAN: return "boolean"; - case xmlpp::XPATH_RESULT_NUMBER: return "number"; - case xmlpp::XPATH_RESULT_STRING: return "string"; + case xmlpp::XPathResultType::NODESET: return "nodeset"; + case xmlpp::XPathResultType::BOOLEAN: return "boolean"; + case xmlpp::XPathResultType::NUMBER: return "number"; + case xmlpp::XPathResultType::STRING: return "string"; - case xmlpp::XPATH_RESULT_UNDEFINED: + case xmlpp::XPathResultType::UNDEFINED: default: return "undefined"; } } -bool xpath_test(const xmlpp::Node* node, const Glib::ustring& xpath) +void print_nodeset(const xmlpp::Node::const_NodeSet& set) +{ + // Print the structural paths and the values: + for(const auto& child : set) + { + std::cout << " " << child->get_path2(); + + auto attribute = dynamic_cast(child); + if (attribute) + std::cout << ", value=\"" << attribute->get_value() << "\""; + + auto content_node = dynamic_cast(child); + if (content_node) + std::cout << ", content=\"" << content_node->get_content2() << "\""; + + auto entity_reference = dynamic_cast(child); + if (entity_reference) + std::cout << ", text=\"" << entity_reference->get_original_text2() << "\""; + + auto element = dynamic_cast(child); + if (element) + { + auto text_node = element->get_first_child_text(); + if (text_node) + std::cout << ", first_child_text=\"" << text_node->get_content2() << "\""; + } + std::cout << std::endl; + } +} + +bool xpath_test(const xmlpp::Node* node, const std::string& xpath) { bool result = true; std::cout << std::endl; //Separate tests by an empty line. @@ -51,39 +80,46 @@ bool xpath_test(const xmlpp::Node* node, const Glib::ustring& xpath) try { auto set = node->find(xpath); + std::cout << "find(): " << set.size() << " nodes have been found:" << std::endl; + print_nodeset(set); + } + catch (const xmlpp::exception& ex) + { + std::cerr << "Exception caught from find: " << ex.what() << std::endl; + result = false; + } - std::cout << set.size() << " nodes have been found:" << std::endl; - - //Print the structural paths and the values: - for(const auto& child : set) + try + { + auto var = node->eval_xpath(xpath); + std::cout << "eval_xpath(): "; + switch (var.index()) { - std::cout << " " << child->get_path(); - - auto attribute = dynamic_cast(child); - if (attribute) - std::cout << ", value=\"" << attribute->get_value() << "\""; - - auto content_node = dynamic_cast(child); - if (content_node) - std::cout << ", content=\"" << content_node->get_content() << "\""; - - auto entity_reference = dynamic_cast(child); - if (entity_reference) - std::cout << ", text=\"" << entity_reference->get_original_text() << "\""; - - auto element = dynamic_cast(child); - if (element) - { - auto text_node = element->get_child_text(); - if (text_node) - std::cout << ", child_text=\"" << text_node->get_content() << "\""; - } - std::cout << std::endl; + case 0: // nodeset + { + auto set = std::get<0>(var); + std::cout << set.size() << " nodes have been found:" << std::endl; + print_nodeset(set); + break; + } + case 1: // boolean + std::cout << "Boolean: " << (std::get<1>(var) ? "true" : "false") << std::endl; + break; + case 2: // number + std::cout << "Number: " << std::get<2>(var) << std::endl; + break; + case 3: // string + std::cout << "String: " << std::get<3>(var) << std::endl; + break; + default: + std::cerr << "Unsupported result type." << std::endl; + result = false; + break; } } catch (const xmlpp::exception& ex) { - std::cerr << "Exception caught from find: " << ex.what() << std::endl; + std::cerr << "Exception caught from eval_xpath: " << ex.what() << std::endl; result = false; } @@ -105,10 +141,6 @@ bool xpath_test(const xmlpp::Node* node, const Glib::ustring& xpath) int main(int argc, char* argv[]) { - // Set the global C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if (argc > 1) filepath = argv[1]; //Allow the user to specify a different XML file to parse. @@ -128,6 +160,9 @@ int main(int argc, char* argv[]) // Find all sections, no matter where: result &= xpath_test(root, "//section"); + // Count the number of sections: + result &= !xpath_test(root, "count(//section)"); + // Find the title node (if there is one): result &= xpath_test(root, "title"); diff --git a/examples/dtdvalidation/main.cc b/examples/dtdvalidation/main.cc index d5e594f5..d1abbfce 100644 --- a/examples/dtdvalidation/main.cc +++ b/examples/dtdvalidation/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ @@ -24,16 +21,12 @@ #include #endif -#include +#include #include -#include +#include int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string dtdfilepath; if(argc > 1) dtdfilepath = argv[1]; //Allow the user to specify a different dtd file to use. @@ -61,9 +54,9 @@ int main(int argc, char* argv[]) } /* auto nodeRoot2 = */document.create_root_node("example"); - auto child = document.get_root_node()->add_child("examplechild"); + auto child = document.get_root_node()->add_child_element("examplechild"); child->set_attribute("id", "an_id"); - child->add_child("child_of_child"); + child->add_child_element("child_of_child"); try { @@ -85,4 +78,3 @@ int main(int argc, char* argv[]) } return return_code; } - diff --git a/examples/import_node/example2.xml b/examples/import_node/example2.xml index adf538b5..b55c0685 100644 --- a/examples/import_node/example2.xml +++ b/examples/import_node/example2.xml @@ -1,6 +1,6 @@ added content from other document -grand child content +grand child content diff --git a/examples/import_node/main.cc b/examples/import_node/main.cc index a539721c..5632ba65 100644 --- a/examples/import_node/main.cc +++ b/examples/import_node/main.cc @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -9,18 +8,14 @@ using namespace std; int main (int /* argc */, char** /* argv */) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - try - { + { DomParser example1("example1.xml"); DomParser example2("example2.xml"); - + auto doc1 = example1.get_document(); auto doc2 = example2.get_document(); - + auto root1 = doc1->get_root_node(); auto root2 = doc2->get_root_node(); @@ -34,11 +29,11 @@ int main (int /* argc */, char** /* argv */) // Import an attribute that will replace an existing attribute in the root element. auto attribute_to_add = root2->get_attribute("name"); root1->import_node(attribute_to_add); - + // Import an attribute that will be added to the root element. attribute_to_add = root2->get_attribute("type"); root1->import_node(attribute_to_add); - + // Find the first text child of the first "child" element in example2. auto first_child2 = dynamic_cast(child_list2.front()); if (!first_child2) @@ -46,7 +41,7 @@ int main (int /* argc */, char** /* argv */) cerr << "first_child2 == nullptr" << endl; return EXIT_FAILURE; } - auto text_to_add = first_child2->get_child_text(); + auto text_to_add = first_child2->get_first_child_text(); // Import the text under the first "child" element in example1. // Adjacent text nodes are merged. diff --git a/examples/meson.build b/examples/meson.build new file mode 100644 index 00000000..e9d9bd60 --- /dev/null +++ b/examples/meson.build @@ -0,0 +1,62 @@ +# examples + +# Input: xmlxx_own_dep, build_examples +# Output: - + +example_programs = [ +# [[dir-name], exe-name, [sources], [arguments]] + [['dom_build'], 'example', ['main.cc'], []], + [['dom_parse_entities'], 'example', ['main.cc'], []], + [['dom_parser'], 'example', ['main.cc'], []], + [['dom_parser_raw'], 'example', ['main.cc'], []], + [['dom_read_write'], 'example', ['main.cc'], + ['example.xml', meson.current_build_dir() / 'dom_read_write_example_output.xml']], + [['dom_update_namespace'], 'example', ['main.cc'], []], + [['dom_xinclude'], 'example', ['main.cc'], []], + [['dom_xpath'], 'example', ['main.cc'], []], + [['dtdvalidation'], 'example', ['main.cc'], []], + [['import_node'], 'example', ['main.cc'], []], + [['sax_exception'], 'example', ['main.cc', 'myparser.cc'], []], + [['sax_parser'], 'example', ['main.cc', 'myparser.cc'], []], + [['sax_parser_build_dom'], 'example', ['main.cc', 'svgparser.cc', + 'svgdocument.cc', 'svgelement.cc'], []], + [['sax_parser_entities'], 'example', ['main.cc', 'myparser.cc'], []], + [['schemavalidation'], 'example', ['main.cc'], []], + [['textreader'], 'example', ['main.cc'], []], +] + +foreach ex : example_programs + dir = '' + foreach dir_part : ex[0] + dir = dir / dir_part + endforeach + ex_name = (dir / ex[1]).underscorify() + ex_sources = [] + foreach src : ex[2] + ex_sources += dir / src + endforeach + + exe_file = executable(ex_name, ex_sources, + dependencies: xmlxx_own_dep, + implicit_include_directories: false, + build_by_default: build_examples, + install: false, + ) + + if build_examples + # Some programs can find their input file(s) only if the current directory, + # when they are executed, is the program's own source directory. + # To make these program invocations as consistent as possible, and to avoid + # having to specify parameters for the programs, the programs are executed + # from their own source directory. + # + # dom_read_write shall write its output file in the build directory. + # It's necessary to specify parameters when the input file and the output + # file are located in different directories. + + test(ex_name, exe_file, + workdir: meson.current_source_dir() / dir, + args: ex[3], + ) + endif +endforeach diff --git a/examples/sax_exception/main.cc b/examples/sax_exception/main.cc index f5b2c579..67d77553 100644 --- a/examples/sax_exception/main.cc +++ b/examples/sax_exception/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ /* This example is nearly the same than sax_parser, but demonstrate how exception @@ -28,17 +25,13 @@ #endif #include "myparser.h" +#include #include -#include int main(int /* argc */, char** /* argv */) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - MySaxParser parser; - + try { parser.parse_file("example.xml"); diff --git a/examples/sax_exception/myparser.cc b/examples/sax_exception/myparser.cc index 19b5417f..85833fdd 100644 --- a/examples/sax_exception/myparser.cc +++ b/examples/sax_exception/myparser.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* myparser.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include "myparser.h" @@ -32,16 +29,14 @@ MyException::MyException() { } -MyException::~MyException() throw () -{ -} +MyException::~MyException() noexcept = default; -void MyException::Raise() const +void MyException::raise() const { throw *this; } -xmlpp::exception * MyException::Clone() const +xmlpp::exception* MyException::clone() const { return new MyException(*this); } @@ -68,7 +63,7 @@ void MySaxParser::on_end_document() std::cout << "on_end_document()" << std::endl; } -void MySaxParser::on_start_element(const Glib::ustring& name, +void MySaxParser::on_start_element(const xmlpp::ustring& name, const AttributeList& attributes) { std::cout << "node name=" << name << std::endl; @@ -82,32 +77,32 @@ void MySaxParser::on_start_element(const Glib::ustring& name, throw MyException(); } -void MySaxParser::on_end_element(const Glib::ustring& /* name */) +void MySaxParser::on_end_element(const xmlpp::ustring& /* name */) { std::cout << "on_end_element()" << std::endl; } -void MySaxParser::on_characters(const Glib::ustring& text) +void MySaxParser::on_characters(const xmlpp::ustring& text) { std::cout << "on_characters(): " << text << std::endl; } -void MySaxParser::on_comment(const Glib::ustring& text) +void MySaxParser::on_comment(const xmlpp::ustring& text) { std::cout << "on_comment(): " << text << std::endl; } -void MySaxParser::on_warning(const Glib::ustring& text) +void MySaxParser::on_warning(const xmlpp::ustring& text) { std::cout << "on_warning(): " << text << std::endl; } -void MySaxParser::on_error(const Glib::ustring& text) +void MySaxParser::on_error(const xmlpp::ustring& text) { std::cout << "on_error(): " << text << std::endl; } -void MySaxParser::on_fatal_error(const Glib::ustring& text) +void MySaxParser::on_fatal_error(const xmlpp::ustring& text) { std::cout << "on_fatal_error(): " << text << std::endl; } diff --git a/examples/sax_exception/myparser.h b/examples/sax_exception/myparser.h index 7eb3a5d0..4aa15f02 100644 --- a/examples/sax_exception/myparser.h +++ b/examples/sax_exception/myparser.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* myparser.h * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_EXAMPLES_MYPARSER_H @@ -29,8 +26,8 @@ class MyException: public xmlpp::exception public: MyException(); ~MyException() noexcept override; - void Raise() const override; - xmlpp::exception * Clone() const override; + void raise() const override; + xmlpp::exception* clone() const override; }; class MySaxParser : public xmlpp::SaxParser @@ -43,14 +40,14 @@ class MySaxParser : public xmlpp::SaxParser //overrides: void on_start_document() override; void on_end_document() override; - void on_start_element(const Glib::ustring& name, + void on_start_element(const xmlpp::ustring& name, const AttributeList &properties) override; - void on_end_element(const Glib::ustring& name) override; - void on_characters(const Glib::ustring& characters) override; - void on_comment(const Glib::ustring& text) override; - void on_warning(const Glib::ustring& text) override; - void on_error(const Glib::ustring& text) override; - void on_fatal_error(const Glib::ustring& text) override; + void on_end_element(const xmlpp::ustring& name) override; + void on_characters(const xmlpp::ustring& characters) override; + void on_comment(const xmlpp::ustring& text) override; + void on_warning(const xmlpp::ustring& text) override; + void on_error(const xmlpp::ustring& text) override; + void on_fatal_error(const xmlpp::ustring& text) override; }; diff --git a/examples/sax_parser/example.xml b/examples/sax_parser/example.xml index daeb29bf..a7cba9ec 100644 --- a/examples/sax_parser/example.xml +++ b/examples/sax_parser/example.xml @@ -1,6 +1,6 @@ + ]> diff --git a/examples/sax_parser/main.cc b/examples/sax_parser/main.cc index b786780f..16265482 100644 --- a/examples/sax_parser/main.cc +++ b/examples/sax_parser/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,34 +13,29 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif +#include +#include // std::memset() #include #include -#include -#include // std::memset() #include "myparser.h" int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if(argc > 1 ) filepath = argv[1]; //Allow the user to specify a different XML file to parse. else filepath = "example.xml"; - + // Parse the entire document in one go: auto return_code = EXIT_SUCCESS; try @@ -61,7 +54,7 @@ main(int argc, char* argv[]) try { std::cout << std::endl << "Incremental SAX Parser:" << std::endl; - + std::ifstream is(filepath.c_str()); if (!is) throw xmlpp::exception("Could not open file " + filepath); @@ -78,10 +71,7 @@ main(int argc, char* argv[]) is.read(buffer, buffer_size-1); if(is.gcount()) { - // We use Glib::ustring::ustring(InputIterator begin, InputIterator end) - // instead of Glib::ustring::ustring( const char*, size_type ) because it - // expects the length of the string in characters, not in bytes. - Glib::ustring input(buffer, buffer+is.gcount()); + xmlpp::ustring input(buffer, buffer+is.gcount()); parser.parse_chunk(input); } } @@ -97,4 +87,3 @@ main(int argc, char* argv[]) return return_code; } - diff --git a/examples/sax_parser/myparser.cc b/examples/sax_parser/myparser.cc index 03c694c5..fb8335c4 100644 --- a/examples/sax_parser/myparser.cc +++ b/examples/sax_parser/myparser.cc @@ -15,12 +15,10 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include "myparser.h" -#include //For Glib::ConvertError #include @@ -43,7 +41,7 @@ void MySaxParser::on_end_document() std::cout << "on_end_document()" << std::endl; } -void MySaxParser::on_start_element(const Glib::ustring& name, +void MySaxParser::on_start_element(const xmlpp::ustring& name, const AttributeList& attributes) { std::cout << "node name=" << name << std::endl; @@ -51,88 +49,38 @@ void MySaxParser::on_start_element(const Glib::ustring& name, // Print attributes: for(const auto& attr_pair : attributes) { - try - { - std::cout << " Attribute name=" << attr_pair.name << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_start_element(): Exception caught while converting name for std::cout: " << ex.what() << std::endl; - } - - try - { - std::cout << " , value= " << attr_pair.value << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_start_element(): Exception caught while converting value for std::cout: " << ex.what() << std::endl; - } + std::cout << " Attribute name=" << attr_pair.name << std::endl; + std::cout << " , value= " << attr_pair.value << std::endl; } } -void MySaxParser::on_end_element(const Glib::ustring& /* name */) +void MySaxParser::on_end_element(const xmlpp::ustring& /* name */) { std::cout << "on_end_element()" << std::endl; } -void MySaxParser::on_characters(const Glib::ustring& text) +void MySaxParser::on_characters(const xmlpp::ustring& text) { - try - { - std::cout << "on_characters(): " << text << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_characters(): Exception caught while converting text for std::cout: " << ex.what() << std::endl; - } + std::cout << "on_characters(): " << text << std::endl; } -void MySaxParser::on_comment(const Glib::ustring& text) +void MySaxParser::on_comment(const xmlpp::ustring& text) { - try - { - std::cout << "on_comment(): " << text << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_comment(): Exception caught while converting text for std::cout: " << ex.what() << std::endl; - } + std::cout << "on_comment(): " << text << std::endl; } -void MySaxParser::on_warning(const Glib::ustring& text) +void MySaxParser::on_warning(const xmlpp::ustring& text) { - try - { - std::cout << "on_warning(): " << text << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_warning(): Exception caught while converting text for std::cout: " << ex.what() << std::endl; - } + std::cout << "on_warning(): " << text << std::endl; } -void MySaxParser::on_error(const Glib::ustring& text) +void MySaxParser::on_error(const xmlpp::ustring& text) { - try - { - std::cout << "on_error(): " << text << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_error(): Exception caught while converting text for std::cout: " << ex.what() << std::endl; - } + std::cout << "on_error(): " << text << std::endl; } -void MySaxParser::on_fatal_error(const Glib::ustring& text) +void MySaxParser::on_fatal_error(const xmlpp::ustring& text) { - try - { - std::cout << "on_fatal_error(): " << text << std::endl; - } - catch(const Glib::ConvertError& ex) - { - std::cerr << "MySaxParser::on_characters(): Exception caught while converting value for std::cout: " << ex.what() << std::endl; - } + std::cout << "on_fatal_error(): " << text << std::endl; } diff --git a/examples/sax_parser/myparser.h b/examples/sax_parser/myparser.h index 34bece82..dc45c429 100644 --- a/examples/sax_parser/myparser.h +++ b/examples/sax_parser/myparser.h @@ -15,8 +15,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_EXAMPLES_MYPARSER_H @@ -34,14 +33,14 @@ class MySaxParser : public xmlpp::SaxParser //overrides: void on_start_document() override; void on_end_document() override; - void on_start_element(const Glib::ustring& name, + void on_start_element(const xmlpp::ustring& name, const AttributeList& properties) override; - void on_end_element(const Glib::ustring& name) override; - void on_characters(const Glib::ustring& characters) override; - void on_comment(const Glib::ustring& text) override; - void on_warning(const Glib::ustring& text) override; - void on_error(const Glib::ustring& text) override; - void on_fatal_error(const Glib::ustring& text) override; + void on_end_element(const xmlpp::ustring& name) override; + void on_characters(const xmlpp::ustring& characters) override; + void on_comment(const xmlpp::ustring& text) override; + void on_warning(const xmlpp::ustring& text) override; + void on_error(const xmlpp::ustring& text) override; + void on_fatal_error(const xmlpp::ustring& text) override; }; diff --git a/examples/sax_parser_build_dom/main.cc b/examples/sax_parser_build_dom/main.cc index 92e2c9de..bfbd26a6 100644 --- a/examples/sax_parser_build_dom/main.cc +++ b/examples/sax_parser_build_dom/main.cc @@ -1,8 +1,6 @@ -// -*- C++ -*- - /* main.cc * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team * @@ -17,17 +15,12 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - +#include #include #include -#include #include "svgparser.h" #include "svgdocument.h" @@ -38,10 +31,6 @@ int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if(argc > 1 ) filepath = argv[1]; //Allow the user to specify a different XML file to parse. @@ -61,11 +50,11 @@ main(int argc, char* argv[]) // Use the custom DOM auto element = doc.get_root(); - std::cout << "root's name is \"" << element->get_name() << "\"" << std::endl; + std::cout << "root's name is \"" << element->get_name2().value_or("{[(no name)]}") << "\"" << std::endl; auto nl = element->find("//path[@style != '']"); if(!nl.empty()) { - auto path = dynamic_cast(nl[0]); + auto path = dynamic_cast(nl[0]); std::cout << "style of first path node with a style = \"" << path->get_style() << "\"" << std::endl; } } @@ -74,7 +63,6 @@ main(int argc, char* argv[]) std::cerr << "libxml++ exception: " << ex.what() << std::endl; return EXIT_FAILURE; } - + return EXIT_SUCCESS; } - diff --git a/examples/sax_parser_build_dom/svgdocument.cc b/examples/sax_parser_build_dom/svgdocument.cc index db4aceb4..82387312 100644 --- a/examples/sax_parser_build_dom/svgdocument.cc +++ b/examples/sax_parser_build_dom/svgdocument.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* svgdocument.cc * * By Dan Dennedy @@ -17,17 +15,16 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include "svgdocument.h" namespace SVG { -SVG::Element* Document::get_root() const +const SVG::Element* Document::get_root() const { - return dynamic_cast(get_root_node()); // RTTI + return dynamic_cast(get_root_node()); // RTTI } } //namespace SVG diff --git a/examples/sax_parser_build_dom/svgdocument.h b/examples/sax_parser_build_dom/svgdocument.h index 324d8995..f0f32e2d 100644 --- a/examples/sax_parser_build_dom/svgdocument.h +++ b/examples/sax_parser_build_dom/svgdocument.h @@ -1,11 +1,9 @@ -// -*- C++ -*- - /* svgdocument.h * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -17,8 +15,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_SVGDOCUMENT_H @@ -32,7 +29,7 @@ namespace SVG { class Document : public xmlpp::Document { public: - SVG::Element* get_root() const; + const SVG::Element* get_root() const; // TODO: add custom document methods }; diff --git a/examples/sax_parser_build_dom/svgelement.cc b/examples/sax_parser_build_dom/svgelement.cc index d2e07ee3..fc7fde62 100644 --- a/examples/sax_parser_build_dom/svgelement.cc +++ b/examples/sax_parser_build_dom/svgelement.cc @@ -1,8 +1,6 @@ -// -*- C++ -*- - /* svgelement.cc * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team * @@ -17,8 +15,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include "svgelement.h" @@ -28,17 +25,17 @@ namespace SVG { Element::Element(xmlNode* node) : xmlpp::Element(node) {} - + Element::~Element() {} // example custom methods -void Element::set_style(const Glib::ustring& style) +void Element::set_style(const xmlpp::ustring& style) { set_attribute("style", style); } - -const Glib::ustring Element::get_style() const + +const xmlpp::ustring Element::get_style() const { return get_attribute("style")->get_value(); } diff --git a/examples/sax_parser_build_dom/svgelement.h b/examples/sax_parser_build_dom/svgelement.h index 1ea8ce1c..c371990f 100644 --- a/examples/sax_parser_build_dom/svgelement.h +++ b/examples/sax_parser_build_dom/svgelement.h @@ -1,11 +1,9 @@ -// -*- C++ -*- - /* svgelement.h * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -17,14 +15,13 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_SVGELEMENT_H #define __LIBXMLPP_SVGELEMENT_H -#include +#include "libxml++/ustring.h" #include #include @@ -34,14 +31,14 @@ class Element : public xmlpp::Element { public: - Element(xmlNode* node); + explicit Element(xmlNode* node); ~Element() override; // example custom methods - void set_style(const Glib::ustring& style); - const Glib::ustring get_style() const; - - // TODO: add custom methods + void set_style(const xmlpp::ustring& style); + const xmlpp::ustring get_style() const; + + // TODO: add custom methods private: // TODO: add custom properties diff --git a/examples/sax_parser_build_dom/svggroup.h b/examples/sax_parser_build_dom/svggroup.h index dd288e16..d4f3c905 100644 --- a/examples/sax_parser_build_dom/svggroup.h +++ b/examples/sax_parser_build_dom/svggroup.h @@ -1,11 +1,9 @@ -// -*- C++ -*- - /* svggroup.h * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -17,8 +15,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_SVGGROUP_H @@ -32,7 +29,7 @@ namespace SVG { class Group : public Element { public: - Group(xmlNode* node) + explicit Group(xmlNode* node) : Element(node) {} }; diff --git a/examples/sax_parser_build_dom/svgparser.cc b/examples/sax_parser_build_dom/svgparser.cc index 6e474a7c..fe32385b 100644 --- a/examples/sax_parser_build_dom/svgparser.cc +++ b/examples/sax_parser_build_dom/svgparser.cc @@ -1,8 +1,6 @@ -// -*- C++ -*- - /* svgparser.cc * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team * @@ -17,8 +15,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include @@ -41,19 +38,19 @@ Parser::~Parser() { } -void Parser::on_start_element(const Glib::ustring& name, +void Parser::on_start_element(const xmlpp::ustring& name, const AttributeList& attributes) { //This method replaces the normal libxml++ node //with an instance of a derived node. //This is not a recommended technique, and might not //work with future versions of libxml++. - + // Parse namespace prefix and save for later: - Glib::ustring elementPrefix; - Glib::ustring elementName = name; - Glib::ustring::size_type idx = name.find(':'); - if (idx != Glib::ustring::npos) //If the separator was found + xmlpp::ustring elementPrefix; + xmlpp::ustring elementName = name; + xmlpp::ustring::size_type idx = name.find(':'); + if (idx != xmlpp::ustring::npos) //If the separator was found { elementPrefix = name.substr(0, idx); elementName = name.substr(idx + 1); @@ -69,7 +66,7 @@ void Parser::on_start_element(const Glib::ustring& name, else { // Create the other elements as child nodes of the last nodes: - element_normal = m_context.top()->add_child(elementName); + element_normal = m_context.top()->add_child_element(elementName); } // TODO: The following is a hack because it leverages knowledge of libxml++ @@ -82,7 +79,7 @@ void Parser::on_start_element(const Glib::ustring& name, delete element_normal; element_normal = nullptr; - // TODO: Again, this requires knowledge of the libxml++ implemenation - + // TODO: Again, this requires knowledge of the libxml++ implementation - // specifically that the base xmlpp::Node() constructor will reassociate // the underyling C instance with this new C++ instance, by seeting _private. // @@ -111,7 +108,7 @@ void Parser::on_start_element(const Glib::ustring& name, const auto attr_name = attr_pair.name; const auto attr_value = attr_pair.value; const auto idx_colon = attr_name.find(':'); - if (idx_colon == Glib::ustring::npos) // If the separator was not found. + if (idx_colon == xmlpp::ustring::npos) // If the separator was not found. { if (attr_name == "xmlns") // This is a namespace declaration. { @@ -148,19 +145,19 @@ void Parser::on_start_element(const Glib::ustring& name, } } -void Parser::on_end_element(const Glib::ustring& /* name */) +void Parser::on_end_element(const xmlpp::ustring& /* name */) { // This causes the next child elements to be added to the sibling, not this node. m_context.pop(); } -void Parser::on_characters(const Glib::ustring& text) +void Parser::on_characters(const xmlpp::ustring& text) { if(!m_context.empty()) m_context.top()->add_child_text(text); } -void Parser::on_comment(const Glib::ustring& text) +void Parser::on_comment(const xmlpp::ustring& text) { if(!m_context.empty()) m_context.top()->add_child_comment(text); @@ -168,22 +165,22 @@ void Parser::on_comment(const Glib::ustring& text) m_doc.add_comment(text); } -void Parser::on_warning(const Glib::ustring& text) +void Parser::on_warning(const xmlpp::ustring& text) { std::cout << "on_warning(): " << text << std::endl; } -void Parser::on_error(const Glib::ustring& text) +void Parser::on_error(const xmlpp::ustring& text) { std::cout << "on_error(): " << text << std::endl; } -void Parser::on_fatal_error(const Glib::ustring& text) +void Parser::on_fatal_error(const xmlpp::ustring& text) { std::cout << "on_fatal_error(): " << text << std::endl; } -void Parser::on_cdata_block(const Glib::ustring& text) +void Parser::on_cdata_block(const xmlpp::ustring& text) { if(!m_context.empty()) m_context.top()->add_child_cdata(text); diff --git a/examples/sax_parser_build_dom/svgparser.h b/examples/sax_parser_build_dom/svgparser.h index b7d99fcf..111d9ac0 100644 --- a/examples/sax_parser_build_dom/svgparser.h +++ b/examples/sax_parser_build_dom/svgparser.h @@ -1,11 +1,9 @@ -// -*- C++ -*- - /* svgparser.h * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -17,15 +15,14 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_SVGPARSER_H #define __LIBXMLPP_SVGPARSER_H #include -#include +#include "libxml++/ustring.h" #include namespace SVG { @@ -33,22 +30,22 @@ namespace SVG { class Parser : public xmlpp::SaxParser { public: - Parser(xmlpp::Document& document); + explicit Parser(xmlpp::Document& document); ~Parser() override; protected: // SAX parser callbacks - void on_start_document() {}; - void on_end_document() {}; - void on_start_element(const Glib::ustring& name, - const AttributeList& properties); - void on_end_element(const Glib::ustring& name); - void on_characters(const Glib::ustring& characters); - void on_comment(const Glib::ustring& text); - void on_warning(const Glib::ustring& text); - void on_error(const Glib::ustring& text); - void on_fatal_error(const Glib::ustring& text); - void on_cdata_block(const Glib::ustring& text); + void on_start_document() override {}; + void on_end_document() override {}; + void on_start_element(const xmlpp::ustring& name, + const AttributeList& properties) override; + void on_end_element(const xmlpp::ustring& name) override; + void on_characters(const xmlpp::ustring& characters) override; + void on_comment(const xmlpp::ustring& text) override; + void on_warning(const xmlpp::ustring& text) override; + void on_error(const xmlpp::ustring& text) override; + void on_fatal_error(const xmlpp::ustring& text) override; + void on_cdata_block(const xmlpp::ustring& text) override; private: // context is a stack to keep track of parent node while the SAX parser diff --git a/examples/sax_parser_build_dom/svgpath.h b/examples/sax_parser_build_dom/svgpath.h index 990546be..2d9e7f98 100644 --- a/examples/sax_parser_build_dom/svgpath.h +++ b/examples/sax_parser_build_dom/svgpath.h @@ -1,11 +1,9 @@ -// -*- C++ -*- - /* svgpath.h * - * By Dan Dennedy + * By Dan Dennedy * * Copyright (C) 2003 The libxml++ development team - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -17,14 +15,13 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_SVGPATH_H #define __LIBXMLPP_SVGPATH_H -#include +#include "libxml++/ustring.h" #include #include "svgelement.h" @@ -33,11 +30,11 @@ namespace SVG { class Path : public Element { public: - Path(xmlNode* node) + explicit Path(xmlNode* node) : Element(node) {} - - const Glib::ustring get_data() const + + const xmlpp::ustring get_data() const { return get_attribute("d")->get_value(); } diff --git a/examples/sax_parser_entities/example.xml b/examples/sax_parser_entities/example.xml index daeb29bf..a7cba9ec 100644 --- a/examples/sax_parser_entities/example.xml +++ b/examples/sax_parser_entities/example.xml @@ -1,6 +1,6 @@ + ]> diff --git a/examples/sax_parser_entities/main.cc b/examples/sax_parser_entities/main.cc index 1466c8db..e2d558c2 100644 --- a/examples/sax_parser_entities/main.cc +++ b/examples/sax_parser_entities/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,27 +13,22 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif +#include #include #include -#include #include "myparser.h" int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string filepath; if(argc > 1 ) filepath = argv[1]; //Allow the user to specify a different XML file to parse. @@ -53,7 +46,7 @@ main(int argc, char* argv[]) std::cerr << "libxml++ exception: " << ex.what() << std::endl; return EXIT_FAILURE; } - + return EXIT_SUCCESS; } diff --git a/examples/sax_parser_entities/myparser.cc b/examples/sax_parser_entities/myparser.cc index c891fcf1..d8b4a980 100644 --- a/examples/sax_parser_entities/myparser.cc +++ b/examples/sax_parser_entities/myparser.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* myparser.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #include "myparser.h" @@ -42,7 +39,7 @@ void MySaxParser::on_end_document() std::cout << "on_end_document()" << std::endl; } -void MySaxParser::on_start_element(const Glib::ustring& name, +void MySaxParser::on_start_element(const xmlpp::ustring& name, const AttributeList& attributes) { std::cout << "node name=" << name << std::endl; @@ -54,50 +51,48 @@ void MySaxParser::on_start_element(const Glib::ustring& name, } } -void MySaxParser::on_end_element(const Glib::ustring& /* name */) +void MySaxParser::on_end_element(const xmlpp::ustring& /* name */) { std::cout << "on_end_element()" << std::endl; } -void MySaxParser::on_characters(const Glib::ustring& text) +void MySaxParser::on_characters(const xmlpp::ustring& text) { std::cout << "on_characters(): " << text << std::endl; } -void MySaxParser::on_comment(const Glib::ustring& text) +void MySaxParser::on_comment(const xmlpp::ustring& text) { std::cout << "on_comment(): " << text << std::endl; } -void MySaxParser::on_warning(const Glib::ustring& text) +void MySaxParser::on_warning(const xmlpp::ustring& text) { std::cout << "on_warning(): " << text << std::endl; } -void MySaxParser::on_error(const Glib::ustring& text) +void MySaxParser::on_error(const xmlpp::ustring& text) { std::cout << "on_error(): " << text << std::endl; } -void MySaxParser::on_fatal_error(const Glib::ustring& text) +void MySaxParser::on_fatal_error(const xmlpp::ustring& text) { std::cout << "on_fatal_error(): " << text << std::endl; } -_xmlEntity* MySaxParser::on_get_entity(const Glib::ustring& name) +_xmlEntity* MySaxParser::on_get_entity(const xmlpp::ustring& name) { std::cout << "on_get_entity(): " << name << std::endl; - + //Call the base class: return SaxParser::on_get_entity(name); } -void MySaxParser::on_entity_declaration(const Glib::ustring& name, xmlpp::XmlEntityType type, const Glib::ustring& publicId, const Glib::ustring& systemId, const Glib::ustring& content) +void MySaxParser::on_entity_declaration(const xmlpp::ustring& name, xmlpp::XmlEntityType type, const xmlpp::ustring& publicId, const xmlpp::ustring& systemId, const xmlpp::ustring& content) { std::cout << "on_entity_declaration(): name=" << name << ", publicId=" << publicId << ", systemId=" << systemId << ", content=" << content << std::endl; //Call the base class: SaxParser::on_entity_declaration(name, type, publicId, systemId, content); } - - diff --git a/examples/sax_parser_entities/myparser.h b/examples/sax_parser_entities/myparser.h index 91476ff2..61d2f6f6 100644 --- a/examples/sax_parser_entities/myparser.h +++ b/examples/sax_parser_entities/myparser.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* myparser.h * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_EXAMPLES_MYPARSER_H @@ -34,18 +31,18 @@ class MySaxParser : public xmlpp::SaxParser //overrides: void on_start_document() override; void on_end_document() override; - virtual void on_start_element(const Glib::ustring& name, - const AttributeList& properties); - void on_end_element(const Glib::ustring& name) override; - void on_characters(const Glib::ustring& characters) override; - void on_comment(const Glib::ustring& text) override; - void on_warning(const Glib::ustring& text) override; - void on_error(const Glib::ustring& text) override; - void on_fatal_error(const Glib::ustring& text) override; - - _xmlEntity* on_get_entity(const Glib::ustring& name) override; - void on_entity_declaration(const Glib::ustring& name, xmlpp::XmlEntityType type, const Glib::ustring& publicId, const Glib::ustring& systemId, const Glib::ustring& content) override; + void on_start_element(const xmlpp::ustring& name, + const AttributeList& properties) override; + void on_end_element(const xmlpp::ustring& name) override; + void on_characters(const xmlpp::ustring& characters) override; + void on_comment(const xmlpp::ustring& text) override; + void on_warning(const xmlpp::ustring& text) override; + void on_error(const xmlpp::ustring& text) override; + void on_fatal_error(const xmlpp::ustring& text) override; + + _xmlEntity* on_get_entity(const xmlpp::ustring& name) override; + void on_entity_declaration(const xmlpp::ustring& name, xmlpp::XmlEntityType type, + const xmlpp::ustring& publicId, const xmlpp::ustring& systemId, const xmlpp::ustring& content) override; }; - #endif //__LIBXMLPP_EXAMPLES_MYPARSER_H diff --git a/examples/schemavalidation/main.cc b/examples/schemavalidation/main.cc index 4cfddf38..2c6fb29d 100644 --- a/examples/schemavalidation/main.cc +++ b/examples/schemavalidation/main.cc @@ -13,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifdef HAVE_CONFIG_H @@ -27,10 +26,6 @@ int main(int argc, char* argv[]) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); - std::string docfilepath("example.xml"); std::string xsdschemafilepath("example.xsd"); std::string rngschemafilepath("example.rng"); @@ -48,14 +43,9 @@ int main(int argc, char* argv[]) rngschemafilepath = argv[3]; } - Glib::ustring phase; + xmlpp::ustring phase; try { -#ifndef LIBXMLXX_DISABLE_DEPRECATED - phase = "XML"; // XSD schema, old validator class - xmlpp::SchemaValidator schemavalidator(xsdschemafilepath); -#endif // LIBXMLXX_DISABLE_DEPRECATED - phase = "XSD"; xmlpp::XsdValidator xsdvalidator(xsdschemafilepath); @@ -67,12 +57,6 @@ int main(int argc, char* argv[]) phase = "parsing"; xmlpp::DomParser parser(docfilepath); -#ifndef LIBXMLXX_DISABLE_DEPRECATED - phase = "XML validating"; - schemavalidator.validate(parser.get_document()); - std::cout << "Valid document, SchemaValidator" << std::endl; -#endif // LIBXMLXX_DISABLE_DEPRECATED - phase = "XSD validating"; xsdvalidator.validate(parser.get_document()); std::cout << "Valid document, XsdValidator" << std::endl; diff --git a/examples/testutilities.cc b/examples/testutilities.cc deleted file mode 100644 index 4509e822..00000000 --- a/examples/testutilities.cc +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2013 The libxml++ development team - * - * This file is part of libxml++. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include "testutilities.h" -#include - -std::ostream& operator<<(std::ostream& os, const CatchConvertError& utf8_string) -{ - try - { - os << static_cast(utf8_string); - } - catch (const Glib::ConvertError& ex) - { - os << "[Glib::ConvertError: " << ex.what() << "]"; - } - return os; -} diff --git a/examples/testutilities.h b/examples/testutilities.h deleted file mode 100644 index 31576d00..00000000 --- a/examples/testutilities.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2013 The libxml++ development team - * - * This file is part of libxml++. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include - -// CatchConvertError is identical to Glib::ustring, except that -// std::ostream& operator<<(std::ostream&, const CatchConvertError&) -// catches Glib::ConvertError, and prints the exception message. -// -// If a printed string contains characters that don't exist in the global -// locale's character set, an exception is thrown, but it's caught locally, -// and the program continues. -// This is particularly useful when the example programs are run by 'make check'. -// If the user-specified locale's character set does not contain all characters -// in the Glib::ustring, operator<<(std::ostream&, const Glib::ustring&) throws -// a Glib::ConvertError exception. That exception is not the result of an error -// in libxml++ or libxml2. -// See also https://bugzilla.gnome.org/show_bug.cgi?id=702136 - -class CatchConvertError : public Glib::ustring -{ -public: - explicit CatchConvertError(const Glib::ustring& str) - : Glib::ustring(str) - { } -}; - -std::ostream& operator<<(std::ostream& os, const CatchConvertError& utf8_string); - diff --git a/examples/textreader/main.cc b/examples/textreader/main.cc index 5b97f32b..da5d85b4 100644 --- a/examples/textreader/main.cc +++ b/examples/textreader/main.cc @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* main.cc * * Copyright (C) 2002 The libxml++ development team @@ -15,23 +13,16 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif - #include -#include - +#include #include -#include struct indent { int depth_; - indent(int depth): depth_(depth) {}; + explicit indent(int depth): depth_(depth) {}; }; std::ostream & operator<<(std::ostream & o, indent const & in) @@ -43,12 +34,14 @@ std::ostream & operator<<(std::ostream & o, indent const & in) return o; } -int main(int /* argc */, char** /* argv */) +std::ostream& operator<<(std::ostream& o, const std::optional& s) { - // Set the global C and C++ locale to the user-configured locale, - // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions. - std::locale::global(std::locale("")); + o << s.value_or("{[(no value)]}"); + return o; +} +int main(int /* argc */, char** /* argv */) +{ try { xmlpp::TextReader reader("example.xml"); @@ -57,16 +50,18 @@ int main(int /* argc */, char** /* argv */) { int depth = reader.get_depth(); std::cout << indent(depth) << "--- node ---" << std::endl; - std::cout << indent(depth) << "name: " << reader.get_name() << std::endl; + std::cout << indent(depth) << "name: " << reader.get_name2() << std::endl; std::cout << indent(depth) << "depth: " << reader.get_depth() << std::endl; if(reader.has_attributes()) { std::cout << indent(depth) << "attributes: " << std::endl; + std::cout << indent(depth) << "attribute 0: " << reader.get_attribute2(0) << std::endl; + std::cout << indent(depth) << "attribute 9: " << reader.get_attribute2(9) << std::endl; reader.move_to_first_attribute(); do { - std::cout << indent(depth) << " " << reader.get_name() << ": " << reader.get_value() << std::endl; + std::cout << indent(depth) << " " << reader.get_name2() << ": " << reader.get_value2() << std::endl; } while(reader.move_to_next_attribute()); reader.move_to_element(); } @@ -75,11 +70,7 @@ int main(int /* argc */, char** /* argv */) std::cout << indent(depth) << "no attributes" << std::endl; } - if(reader.has_value()) - std::cout << indent(depth) << "value: '" << reader.get_value() << "'" << std::endl; - else - std::cout << indent(depth) << "novalue" << std::endl; - + std::cout << indent(depth) << "value: '" << reader.get_value2() << "'" << std::endl; } } catch(const std::exception& e) diff --git a/libxml++-2.6.pc.in b/libxml++.pc.in similarity index 67% rename from libxml++-2.6.pc.in rename to libxml++.pc.in index b6189c12..5d8d1dc3 100644 --- a/libxml++-2.6.pc.in +++ b/libxml++.pc.in @@ -8,12 +8,12 @@ includedir=@includedir@ docdir=${datarootdir}/doc/@LIBXMLXX_MODULE_NAME@ doxytagfile=${docdir}/reference/@LIBXMLXX_MODULE_NAME@.tag htmlrefdir=${docdir}/reference/html -htmlrefpub=http://library.gnome.org/devel/@PACKAGE_TARNAME@/unstable/ +htmlrefpub=https://libxmlplusplus.github.io/libxmlplusplus/reference/html/ Name: libxml++ Description: C++ wrapper for libxml Version: @PACKAGE_VERSION@ -URL: http://libxmlplusplus.sourceforge.net/ +URL: https://libxmlplusplus.github.io/libxmlplusplus/ Requires: @LIBXMLXX_MODULES@ -Libs: -L${libdir} -lxml++-@LIBXMLXX_API_VERSION@ +Libs: -L${libdir} -lxml++@MSVC_TOOLSET_VER@-@LIBXMLXX_API_VERSION@ @LIBXML2_LIB_NO_PKGCONFIG@ Cflags: -I${includedir}/@LIBXMLXX_MODULE_NAME@ -I${libdir}/@LIBXMLXX_MODULE_NAME@/include diff --git a/libxml++/attribute.cc b/libxml++/attribute.cc index 949afd51..e10d1a50 100644 --- a/libxml++/attribute.cc +++ b/libxml++/attribute.cc @@ -6,6 +6,7 @@ #include "libxml++/attribute.h" #include "libxml++/attributedeclaration.h" +#include "libxml++/attributenode.h" #include @@ -21,61 +22,15 @@ Attribute::~Attribute() { } -Glib::ustring Attribute::get_name() const +std::optional Attribute::get_value2() const { - // This will get the name also for an AttributeDeclaration. The name is in - // the same position in xmlNode, xmlAttr and xmlAttribute. - return cobj()->name ? (char*)cobj()->name : Glib::ustring(); -} - -//TODO when we can break ABI: Make get_value() virtual. -Glib::ustring Attribute::get_value() const -{ - const AttributeDeclaration* const attributeDecl = - dynamic_cast(this); - if (attributeDecl) // AttributeDeclaration - return attributeDecl->get_value(); - - // AttributeNode - xmlChar* value = nullptr; - if (cobj()->ns && cobj()->ns->href) - value = xmlGetNsProp(cobj()->parent, cobj()->name, cobj()->ns->href); - else - value = xmlGetNoNsProp(cobj()->parent, cobj()->name); - - const Glib::ustring retn = value ? (const char*)value : ""; - if (value) - xmlFree(value); - return retn; -} - -//TODO when we can break ABI: Move set_value() to AttributeNode. -void Attribute::set_value(const Glib::ustring& value) -{ - if (dynamic_cast(this)) - return; // Won't change the value of an AttributeDeclaration - - if (cobj()->ns) - xmlSetNsProp(cobj()->parent, cobj()->ns, cobj()->name, (const xmlChar*)value.c_str()); - else - xmlSetProp(cobj()->parent, cobj()->name, (const xmlChar*)value.c_str()); -} - -xmlAttr* Attribute::cobj() -{ - // yes, this does what it looks like: it takes an xmlNode pointer - // and *reinterprets* it as an xmlAttr pointer - // -stefan - return reinterpret_cast(Node::cobj()); -} - -const xmlAttr* Attribute::cobj() const -{ - // yes, this does what it looks like: it takes an xmlNode pointer - // and *reinterprets* it as an xmlAttr pointer - // -stefan - return reinterpret_cast(Node::cobj()); + auto attr_decl = dynamic_cast(this); + if (attr_decl) + return attr_decl->get_value2(); + auto attr_node = dynamic_cast(this); + if (attr_node) + return attr_node->get_value2(); + return {}; } } //namespace xmlpp - diff --git a/libxml++/attribute.h b/libxml++/attribute.h index 37945822..9e902713 100644 --- a/libxml++/attribute.h +++ b/libxml++/attribute.h @@ -7,67 +7,36 @@ #ifndef __LIBXMLPP_ATTRIBUTE_H #define __LIBXMLPP_ATTRIBUTE_H - -#include - +#include "libxml++/ustring.h" #include +#include -#ifndef DOXYGEN_SHOULD_SKIP_THIS -extern "C" { - struct _xmlAttr; -} -#endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS - +//TODO: When we can break API/ABI, remove get_value(), rename get_value2() +// to get_value(), make it virtual. Do the same in AttributeDeclaration and +// AttributeNmode. namespace xmlpp { -/** Represents an XML Node attribute. +/** Represents an XML attribute node or attribute declaration. * This will be instantiated by the parser. */ -class Attribute : public Node +class LIBXMLPP_API Attribute : public Node { public: explicit Attribute(_xmlNode* node); ~Attribute() override; - - //TODO: Can we remove this and just use Node::get_name()? - // Yes, when we can break ABI. /Kjell Ahlstedt 2012-02-09 - - /** Get the name of this attribute. - * See also Node::get_namespace_prefix() and Node::get_namespace_uri() - * @returns The attribute's name. - */ - Glib::ustring get_name() const; /** Get the value of this attribute. - * Can be used for both an AttributeDeclaration and an AttributeNode. * @returns The attribute's value. + * @deprecated 5.6: Use get_value2() instead. */ - Glib::ustring get_value() const; + virtual ustring get_value() const = 0; - /** Set the value of this attribute. - * - * If this is an AttributeDeclaration, the value will not be changed. - * This method is here for backward compatibility. It may be moved to - * AttributeNode in the future. - */ - void set_value(const Glib::ustring& value); - - /** Access the underlying libxml implementation. - * - * If this is an AttributeDeclaration, use AttributeDeclaration::cobj() instead. - * This method is here for backward compatibility. It may be moved to - * AttributeNode in the future. - */ - _xmlAttr* cobj(); - - /** Access the underlying libxml implementation. - * - * If this is an AttributeDeclaration, use AttributeDeclaration::cobj() instead. - * This method is here for backward compatibility. It may be moved to - * AttributeNode in the future. + /** Get the value of this attribute. + * @returns The attribute's value, or no value if the attribute has no value. + * @newin{5,6} */ - const _xmlAttr* cobj() const; + std::optional get_value2() const; }; } // namespace xmlpp diff --git a/libxml++/attributedeclaration.cc b/libxml++/attributedeclaration.cc index 16ff57bd..f15ce60b 100644 --- a/libxml++/attributedeclaration.cc +++ b/libxml++/attributedeclaration.cc @@ -20,19 +20,26 @@ AttributeDeclaration::~AttributeDeclaration() { } -Glib::ustring AttributeDeclaration::get_value() const +ustring AttributeDeclaration::get_value() const { + return cobj()->defaultValue ? (const char*)cobj()->defaultValue : ""; +} + +std::optional AttributeDeclaration::get_value2() const +{ + if (!cobj()->defaultValue) + return {}; return (const char*)cobj()->defaultValue; } -xmlAttribute* AttributeDeclaration::cobj() +xmlAttribute* AttributeDeclaration::cobj() noexcept { // An XML_ATTRIBUTE_DECL is represented by an xmlAttribute struct. Reinterpret // the xmlNode pointer stored in the base class as an xmlAttribute pointer. return reinterpret_cast(Node::cobj()); } -const xmlAttribute* AttributeDeclaration::cobj() const +const xmlAttribute* AttributeDeclaration::cobj() const noexcept { // An XML_ATTRIBUTE_DECL is represented by an xmlAttribute struct. Reinterpret // the xmlNode pointer stored in the base class as an xmlAttribute pointer. diff --git a/libxml++/attributedeclaration.h b/libxml++/attributedeclaration.h index 3178cf39..c14f765a 100644 --- a/libxml++/attributedeclaration.h +++ b/libxml++/attributedeclaration.h @@ -7,7 +7,7 @@ #ifndef __LIBXMLPP_ATTRIBUTEDECLARATION_H #define __LIBXMLPP_ATTRIBUTEDECLARATION_H -#include +#include "libxml++/ustring.h" #include @@ -20,12 +20,12 @@ extern "C" { namespace xmlpp { -/** Represents the default value of an attribute of an XML Element node. +/** Represents the default value of an attribute of an XML element node. * This will be instantiated by the parser. * * @newin{2,36} */ -class AttributeDeclaration : public Attribute +class LIBXMLPP_API AttributeDeclaration : public Attribute { public: explicit AttributeDeclaration(_xmlNode* node); @@ -33,14 +33,22 @@ class AttributeDeclaration : public Attribute /** Get the default value of this attribute. * @returns The attribute's default value. + * @deprecated 5.6: Use get_value2() instead. */ - Glib::ustring get_value() const; + ustring get_value() const override; + + /** Get the default value of this attribute. + * @returns The attribute's default value, or not value if the attribute + * has no default value. + * @newin{5,6} + */ + std::optional get_value2() const; ///Access the underlying libxml implementation. - _xmlAttribute* cobj(); + _xmlAttribute* cobj() noexcept; ///Access the underlying libxml implementation. - const _xmlAttribute* cobj() const; + const _xmlAttribute* cobj() const noexcept; }; } // namespace xmlpp diff --git a/libxml++/attributenode.cc b/libxml++/attributenode.cc index a8744158..44d2f4ac 100644 --- a/libxml++/attributenode.cc +++ b/libxml++/attributenode.cc @@ -20,4 +20,56 @@ AttributeNode::~AttributeNode() { } +ustring AttributeNode::get_value() const +{ + xmlChar* value = nullptr; + if (cobj()->ns && cobj()->ns->href) + value = xmlGetNsProp(cobj()->parent, cobj()->name, cobj()->ns->href); + else + value = xmlGetNoNsProp(cobj()->parent, cobj()->name); + + ustring retn = value ? (const char*)value : ""; + if (value) + xmlFree(value); + return retn; +} + +std::optional AttributeNode::get_value2() const +{ + xmlChar* value = nullptr; + if (cobj()->ns && cobj()->ns->href) + value = xmlGetNsProp(cobj()->parent, cobj()->name, cobj()->ns->href); + else + value = xmlGetNoNsProp(cobj()->parent, cobj()->name); + + if (!value) + return {}; + + std::optional result = (const char*)value; + xmlFree(value); + return result; +} + +void AttributeNode::set_value(const ustring& value) +{ + if (cobj()->ns) + xmlSetNsProp(cobj()->parent, cobj()->ns, cobj()->name, (const xmlChar*)value.c_str()); + else + xmlSetProp(cobj()->parent, cobj()->name, (const xmlChar*)value.c_str()); +} + +xmlAttr* AttributeNode::cobj() noexcept +{ + // An XML_ATTRIBUTE_NODE is represented by an xmlAttr struct. Reinterpret + // the xmlNode pointer stored in the base class as an xmlAttr pointer. + return reinterpret_cast(Node::cobj()); +} + +const xmlAttr* AttributeNode::cobj() const noexcept +{ + // An XML_ATTRIBUTE_NODE is represented by an xmlAttr struct. Reinterpret + // the xmlNode pointer stored in the base class as an xmlAttr pointer. + return reinterpret_cast(Node::cobj()); +} + } //namespace xmlpp diff --git a/libxml++/attributenode.h b/libxml++/attributenode.h index a60874f9..a72250c5 100644 --- a/libxml++/attributenode.h +++ b/libxml++/attributenode.h @@ -8,23 +8,59 @@ #define __LIBXMLPP_ATTRIBUTENODE_H -#include +#include "libxml++/ustring.h" #include +#ifndef DOXYGEN_SHOULD_SKIP_THIS +extern "C" { + struct _xmlAttr; +} +#endif //#ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace xmlpp { -/** Represents an explicit attribute of an XML Element node. +/** Represents an explicit attribute of an XML element node. * This will be instantiated by the parser. * * @newin{2,36} */ -class AttributeNode : public Attribute +class LIBXMLPP_API AttributeNode : public Attribute { public: explicit AttributeNode(_xmlNode* node); ~AttributeNode() override; + + /** Get the value of this attribute. + * @returns The attribute's value. + * @deprecated 5.6: Use get_value2() instead. + */ + ustring get_value() const override; + + /** Get the value of this attribute. + * @returns The attribute's value, or no value if the attribute has no value. + * @newin{5,6} + */ + std::optional get_value2() const; + + /** Set the value of this attribute. + * + * @newin{3,0} Replaces Attribute::set_value() + */ + void set_value(const ustring& value); + + /** Access the underlying libxml implementation. + * + * @newin{3,0} Replaces Attribute::cobj() + */ + _xmlAttr* cobj() noexcept; + + /** Access the underlying libxml implementation. + * + * @newin{3,0} Replaces Attribute::cobj() const + */ + const _xmlAttr* cobj() const noexcept; }; } // namespace xmlpp diff --git a/libxml++/document.cc b/libxml++/document.cc index e4f5c1c5..9222a6e3 100644 --- a/libxml++/document.cc +++ b/libxml++/document.cc @@ -7,24 +7,28 @@ * which should be included with libxml++ as the file COPYING. */ +// xmlIndentTreeOutput is deprecated since libxml2 2.15.0. +// Ignore deprecations here. +#define XML_DEPRECATED + #include #include -#include #include #include #include #include +#include // XML_PARSE_NOXINCNODE, XML_PARSE_NOBASEFIX #include #include -#include // XML_PARSE_NOXINCNODE +#include #include #include namespace // anonymous { -typedef std::map NodeMap; +using NodeMap = std::map; // Find all C++ wrappers of 'node' and its descendants. // Compare xmlpp::Node::free_wrappers(). @@ -32,7 +36,7 @@ void find_wrappers(xmlNode* node, NodeMap& node_map) { if (!node) return; - + //If an entity declaration contains an entity reference, there can be cyclic //references between entity declarations and entity references. (It's not //a tree.) We must avoid an infinite recursion. @@ -57,6 +61,7 @@ void find_wrappers(xmlNode* node, NodeMap& node_map) case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: has_attributes = false; break; default: @@ -70,9 +75,9 @@ void find_wrappers(xmlNode* node, NodeMap& node_map) return; //Walk the attributes list. - //Note that some "derived" structs have a different layout, so + //Note that some "derived" structs have a different layout, so //_xmlNode::properties would be a nonsense value, leading to crashes - //(and shown as valgrind warnings), so we return above, to avoid + //(and shown as valgrind warnings), so we return above, to avoid //checking it here. for (auto attr = node->properties; attr; attr = attr->next) find_wrappers(reinterpret_cast(attr), node_map); @@ -84,7 +89,7 @@ void remove_found_wrappers(xmlNode* node, NodeMap& node_map) { if (!node) return; - + if (node->type != XML_ENTITY_REF_NODE) { // Walk the children list. @@ -103,6 +108,7 @@ void remove_found_wrappers(xmlNode* node, NodeMap& node_map) case XML_ATTRIBUTE_DECL: case XML_ENTITY_DECL: case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: has_attributes = false; break; default: @@ -135,11 +141,11 @@ void remove_found_wrappers(xmlNode* node, NodeMap& node_map) namespace xmlpp { -static const char* get_encoding_or_utf8(const Glib::ustring& encoding) +static const char* get_encoding_or_utf8(const ustring& encoding) { if(encoding.empty()) { - //If we don't specify this to the xmlDocDump* functions (using 0 instead), + //If we don't specify this to the xmlDocDump* functions (using nullptr instead), //then some other encoding is used, causing them to fail on non-ASCII characters. return "UTF-8"; } @@ -153,7 +159,7 @@ Document::Init::Init() xmlInitParser(); //Not always necessary, but necessary for thread safety. } -Document::Init::~Init() +Document::Init::~Init() noexcept { //We don't call this because it breaks libxml generally and should only be //called at the very end of a process, such as at the end of a main(). @@ -169,7 +175,7 @@ Document::Init::~Init() Document::Init Document::init_; -Document::Document(const Glib::ustring& version) +Document::Document(const ustring& version) : impl_(xmlNewDoc((const xmlChar*)version.c_str())) { if (!impl_) @@ -180,6 +186,9 @@ Document::Document(const Glib::ustring& version) Document::Document(xmlDoc* doc) : impl_(doc) { + if (!impl_) + throw internal_error("xmlDoc pointer cannot be nullptr"); + impl_->_private = this; } @@ -189,20 +198,29 @@ Document::~Document() xmlFreeDoc(impl_); } -Glib::ustring Document::get_encoding() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Document::get_encoding() const { - Glib::ustring encoding; + ustring encoding; if(impl_->encoding) encoding = (const char*)impl_->encoding; return encoding; } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional Document::get_encoding2() const +{ + if (!impl_->encoding) + return {}; + return (const char*)impl_->encoding; +} Dtd* Document::get_internal_subset() const { auto dtd = xmlGetIntSubset(impl_); if(!dtd) - return 0; + return nullptr; if(!dtd->_private) dtd->_private = new Dtd(dtd); @@ -210,24 +228,24 @@ Dtd* Document::get_internal_subset() const return reinterpret_cast(dtd->_private); } -void Document::set_internal_subset(const Glib::ustring& name, - const Glib::ustring& external_id, - const Glib::ustring& system_id) +void Document::set_internal_subset(const ustring& name, + const ustring& external_id, + const ustring& system_id) { auto dtd = xmlCreateIntSubset(impl_, (const xmlChar*)name.c_str(), - external_id.empty() ? (const xmlChar*)0 : (const xmlChar*)external_id.c_str(), - system_id.empty() ? (const xmlChar*)0 : (const xmlChar*)system_id.c_str()); + external_id.empty() ? nullptr : (const xmlChar*)external_id.c_str(), + system_id.empty() ? nullptr : (const xmlChar*)system_id.c_str()); if (dtd && !dtd->_private) dtd->_private = new Dtd(dtd); } -Element* Document::get_root_node() const +Element* Document::get_root_node() { auto root = xmlDocGetRootElement(impl_); if(root == nullptr) - return 0; + return nullptr; else { Node::create_wrapper(root); @@ -235,11 +253,16 @@ Element* Document::get_root_node() const } } -Element* Document::create_root_node(const Glib::ustring& name, - const Glib::ustring& ns_uri, - const Glib::ustring& ns_prefix) +const Element* Document::get_root_node() const +{ + return const_cast(this)->get_root_node(); +} + +Element* Document::create_root_node(const ustring& name, + const ustring& ns_uri, + const ustring& ns_prefix) { - auto node = xmlNewDocNode(impl_, 0, (const xmlChar*)name.c_str(), 0); + auto node = xmlNewDocNode(impl_, nullptr, (const xmlChar*)name.c_str(), nullptr); if (!node) throw internal_error("Could not create root element node " + name); @@ -266,7 +289,7 @@ Element* Document::create_root_node_by_import(const Node* node, bool recursive) { if (!node) - return 0; + return nullptr; //Create the node, by copying: auto imported_node = xmlDocCopyNode(const_cast(node->cobj()), impl_, recursive); @@ -286,10 +309,10 @@ Element* Document::create_root_node_by_import(const Node* node, return get_root_node(); } -CommentNode* Document::add_comment(const Glib::ustring& content) +CommentNode* Document::add_comment(const ustring& content) { auto child = xmlNewComment((const xmlChar*)content.c_str()); - + // Use the result, because child can be freed when merging text nodes: auto node = xmlAddChild((xmlNode*)impl_, child); if (!node) @@ -302,7 +325,7 @@ CommentNode* Document::add_comment(const Glib::ustring& content) } ProcessingInstructionNode* Document::add_processing_instruction( - const Glib::ustring& name, const Glib::ustring& content) + const ustring& name, const ustring& content) { auto child = xmlNewDocPI(impl_, (const xmlChar*)name.c_str(), (const xmlChar*)content.c_str()); auto node = xmlAddChild((xmlNode*)impl_, child); @@ -315,39 +338,39 @@ ProcessingInstructionNode* Document::add_processing_instruction( return static_cast(node->_private); } -void Document::write_to_file(const Glib::ustring& filename, const Glib::ustring& encoding) +void Document::write_to_file(const std::string& filename, const ustring& encoding) { do_write_to_file(filename, encoding, false); } -void Document::write_to_file_formatted(const Glib::ustring& filename, const Glib::ustring& encoding) +void Document::write_to_file_formatted(const std::string& filename, const ustring& encoding) { do_write_to_file(filename, encoding, true); } -Glib::ustring Document::write_to_string(const Glib::ustring& encoding) +ustring Document::write_to_string(const ustring& encoding) { return do_write_to_string(encoding, false); } -Glib::ustring Document::write_to_string_formatted(const Glib::ustring& encoding) +ustring Document::write_to_string_formatted(const ustring& encoding) { return do_write_to_string(encoding, true); } -void Document::write_to_stream(std::ostream& output, const Glib::ustring& encoding) +void Document::write_to_stream(std::ostream& output, const ustring& encoding) { do_write_to_stream(output, encoding.empty()?get_encoding():encoding, false); } -void Document::write_to_stream_formatted(std::ostream& output, const Glib::ustring& encoding) +void Document::write_to_stream_formatted(std::ostream& output, const ustring& encoding) { do_write_to_stream(output, encoding.empty()?get_encoding():encoding, true); } void Document::do_write_to_file( - const Glib::ustring& filename, - const Glib::ustring& encoding, + const std::string& filename, + const ustring& encoding, bool format) { KeepBlanks k(KeepBlanks::Default); @@ -362,8 +385,8 @@ void Document::do_write_to_file( } } -Glib::ustring Document::do_write_to_string( - const Glib::ustring& encoding, +ustring Document::do_write_to_string( + const ustring& encoding, bool format) { KeepBlanks k(KeepBlanks::Default); @@ -380,12 +403,12 @@ Glib::ustring Document::do_write_to_string( throw exception("do_write_to_string() failed.\n" + format_xml_error()); } - // Create a Glib::ustring copy of the buffer + // Create a ustring copy of the buffer - // Here we force the use of Glib::ustring::ustring( InputIterator begin, InputIterator end ) - // instead of Glib::ustring::ustring( const char*, size_type ) because it + // Here we force the use of ustring::ustring( InputIterator begin, InputIterator end ) + // instead of ustring::ustring( const char*, size_type ) because it // expects the length of the string in characters, not in bytes. - Glib::ustring result( reinterpret_cast(buffer), reinterpret_cast(buffer + length) ); + ustring result( reinterpret_cast(buffer), reinterpret_cast(buffer + length) ); // Deletes the original buffer xmlFree(buffer); @@ -393,33 +416,34 @@ Glib::ustring Document::do_write_to_string( return result; } -void Document::do_write_to_stream(std::ostream& output, const Glib::ustring& encoding, bool format) +void Document::do_write_to_stream(std::ostream& output, const ustring& encoding, bool format) { // TODO assert document encoding is UTF-8 if encoding is different than UTF-8 OStreamOutputBuffer buffer(output, encoding); xmlResetLastError(); const int result = xmlSaveFormatFileTo(buffer.cobj(), impl_, get_encoding_or_utf8(encoding), format ? 1 : 0); - + if(result == -1) { throw exception("do_write_to_stream() failed.\n" + format_xml_error()); } } -void Document::set_entity_declaration(const Glib::ustring& name, XmlEntityType type, - const Glib::ustring& publicId, const Glib::ustring& systemId, - const Glib::ustring& content) +void Document::set_entity_declaration(const ustring& name, XmlEntityType type, + const ustring& publicId, const ustring& systemId, + const ustring& content) { - auto entity = xmlAddDocEntity( impl_, (const xmlChar*) name.c_str(), type, - publicId.empty() ? (const xmlChar*)0 : (const xmlChar*)publicId.c_str(), - systemId.empty() ? (const xmlChar*)0 : (const xmlChar*)systemId.c_str(), - (const xmlChar*) content.c_str() ); + auto entity = xmlAddDocEntity(impl_, (const xmlChar*)name.c_str(), + static_cast(type), + publicId.empty() ? nullptr : (const xmlChar*)publicId.c_str(), + systemId.empty() ? nullptr : (const xmlChar*)systemId.c_str(), + (const xmlChar*)content.c_str()); if (!entity) throw internal_error("Could not add entity declaration " + name); } -int Document::process_xinclude(bool generate_xinclude_nodes) +int Document::process_xinclude(bool generate_xinclude_nodes, bool fixup_base_uris) { NodeMap node_map; @@ -428,8 +452,13 @@ int Document::process_xinclude(bool generate_xinclude_nodes) find_wrappers(root, node_map); xmlResetLastError(); - const int n_substitutions = xmlXIncludeProcessTreeFlags(root, - generate_xinclude_nodes ? 0 : XML_PARSE_NOXINCNODE); + + int flags = 0; + if (!generate_xinclude_nodes) + flags |= XML_PARSE_NOXINCNODE; + if (!fixup_base_uris) + flags |= XML_PARSE_NOBASEFIX; + const int n_substitutions = xmlXIncludeProcessTreeFlags(root, flags); remove_found_wrappers(reinterpret_cast(impl_), node_map); @@ -444,6 +473,7 @@ int Document::process_xinclude(bool generate_xinclude_nodes) delete reinterpret_cast(node); break; case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: delete reinterpret_cast(node); break; default: @@ -460,17 +490,17 @@ int Document::process_xinclude(bool generate_xinclude_nodes) return n_substitutions; } -_xmlEntity* Document::get_entity(const Glib::ustring& name) +_xmlEntity* Document::get_entity(const ustring& name) { return xmlGetDocEntity(impl_, (const xmlChar*) name.c_str()); } -_xmlDoc* Document::cobj() +_xmlDoc* Document::cobj() noexcept { return impl_; } -const _xmlDoc* Document::cobj() const +const _xmlDoc* Document::cobj() const noexcept { return impl_; } diff --git a/libxml++/document.h b/libxml++/document.h index eaede6cf..9ae580fa 100644 --- a/libxml++/document.h +++ b/libxml++/document.h @@ -16,8 +16,20 @@ #include #include +#include +#include #include +/* std::string or ustring in function prototypes in libxml++? + * + * If it's propagated to a libxml2 function that takes a xmlChar*, it's + * UTF-8 encoded, and ustring is the right choice. + * + * If it's propagated to a libxml2 function that takes a char*, it's not + * necessarily UTF-8 encoded, and std::string is usually the right choice. + * Most of these strings are filenames or URLs. + */ + #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { struct _xmlDoc; @@ -28,34 +40,37 @@ extern "C" { namespace xmlpp { -typedef enum { - XML_INTERNAL_GENERAL_ENTITY = 1, - XML_EXTERNAL_GENERAL_PARSED_ENTITY = 2, - XML_EXTERNAL_GENERAL_UNPARSED_ENTITY = 3, - XML_INTERNAL_PARAMETER_ENTITY = 4, - XML_EXTERNAL_PARAMETER_ENTITY = 5, - XML_INTERNAL_PREDEFINED_ENTITY = 6 -} XmlEntityType; - -class Document; +// xmlpp::XmlEntityType is similar to xmlEntityType in libxml2. +/** The valid entity types. + */ +enum class XmlEntityType +{ + INTERNAL_GENERAL = 1, + EXTERNAL_GENERAL_PARSED = 2, + EXTERNAL_GENERAL_UNPARSED = 3, + INTERNAL_PARAMETER = 4, + EXTERNAL_PARAMETER = 5, + INTERNAL_PREDEFINED = 6 +}; //TODO: Make Document inherit from Node, when we can break ABI one day? // //libxml might intend xmlDoc to derive (theoretically) from xmlNode. -//This is suggested because the xmlNodeSet returned by xmlXPathEval (see the Node::find() implementation) can contain either xmlNode or xmlDocument elements. +//This is suggested because the xmlNodeSet returned by xmlXPathEval (see the +//Node::find() implementation) can contain either xmlNode or xmlDocument elements. +// See https://bugzilla.gnome.org/show_bug.cgi?id=754673#c8 for an explanation +// why it has not been done in libxml++ 3.0. /** * Represents an XML document in the DOM model. */ -class Document : NonCopyable +class Document : public NonCopyable { //Ensure that libxml is properly initialised: - class Init + class LIBXMLPP_API Init { public: Init(); - - //TODO: Remove the virtual when we can break ABI? - virtual ~Init(); + ~Init() noexcept; }; friend class SaxParser; @@ -65,24 +80,40 @@ class Document : NonCopyable * @param version XML version. * @throws xmlpp::internal_error If memory allocation fails. */ - explicit Document(const Glib::ustring& version = "1.0"); - + LIBXMLPP_API + explicit Document(const ustring& version = "1.0"); + /** Create a new C++ wrapper for an xmlDoc struct. * The created xmlpp::Document takes ownership of the xmlDoc. * When the Document is deleted, so is the xmlDoc and all its nodes. - * @param doc A pointer to an xmlDoc struct. Must not be 0. + * @param doc A pointer to an xmlDoc struct. Must not be nullptr. + * @throws xmlpp::internal_error If @a doc is nullptr. */ - explicit Document(_xmlDoc* doc); - - ~Document() override; + LIBXMLPP_API explicit Document(_xmlDoc* doc); + + LIBXMLPP_API ~Document() override; - /** @return The encoding used in the source from which the document has been loaded. +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Get the encoding used in the source from which the document has been loaded. + * @return The encoding used in the source from which the document has been loaded. + * @deprecated 5.6: Use get_encoding2() instead. + */ + LIBXMLPP_API + ustring get_encoding() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the encoding used in the source from which the document has been loaded. + * @return The encoding used in the source from which the document has been loaded, + * if any, else no value. + * @newin{5,6} */ - Glib::ustring get_encoding() const; + LIBXMLPP_API + std::optional get_encoding2() const; /** Get the internal subset of this document. - * @returns A pointer to the DTD, or 0 if not found. + * @returns A pointer to the DTD, or nullptr if not found. */ + LIBXMLPP_API Dtd* get_internal_subset() const; /** Create the internal subset of this document. @@ -91,17 +122,24 @@ class Document : NonCopyable * @param external_id The external (PUBLIC) ID, or an empty string. * @param system_id The system ID, or an empty string. */ - void set_internal_subset(const Glib::ustring& name, - const Glib::ustring& external_id, - const Glib::ustring& system_id); + LIBXMLPP_API + void set_internal_subset(const ustring& name, + const ustring& external_id, + const ustring& system_id); - //TODO: There should be a const and non-const version. - //See the patch here: https://bugzilla.gnome.org/show_bug.cgi?id=632522 /** Return the root node. * This function does @b not create a default root node if it doesn't exist. - * @return A pointer to the root node if it exists, 0 otherwise. + * @return A pointer to the root node if it exists, nullptr otherwise. */ - Element* get_root_node() const; + LIBXMLPP_API + Element* get_root_node(); + + /** Return the root node. + * This function does @b not create a default root node if it doesn't exist. + * @return A pointer to the root node if it exists, nullptr otherwise. + */ + LIBXMLPP_API + const Element* get_root_node() const; /** Create the root element node. * If the document already contains a root element node, it is replaced, and @@ -115,9 +153,10 @@ class Document : NonCopyable * @throws xmlpp::internal_error If memory allocation fails. * @throws xmlpp::exception If a new namespace node cannot be created. */ - Element* create_root_node(const Glib::ustring& name, - const Glib::ustring& ns_uri = Glib::ustring(), - const Glib::ustring& ns_prefix = Glib::ustring() ); + LIBXMLPP_API + Element* create_root_node(const ustring& name, + const ustring& ns_uri = ustring(), + const ustring& ns_prefix = ustring() ); /** Create a root element node by importing the node from another document, * without affecting the source node. @@ -129,6 +168,7 @@ class Document : NonCopyable * @return A pointer to the new root node * @throws xmlpp::exception If the node can't be copied. */ + LIBXMLPP_API Element* create_root_node_by_import(const Node* node, bool recursive = true); @@ -137,7 +177,8 @@ class Document : NonCopyable * @returns The new comment node. * @throws xmlpp::internal_error */ - CommentNode* add_comment(const Glib::ustring& content); + LIBXMLPP_API + CommentNode* add_comment(const ustring& content); /** Append a new processing instruction node. * @@ -148,16 +189,17 @@ class Document : NonCopyable * @returns The new processing instruction node. * @throws xmlpp::internal_error */ + LIBXMLPP_API ProcessingInstructionNode* add_processing_instruction( - const Glib::ustring& name, const Glib::ustring& content); + const ustring& name, const ustring& content); - //TODO: Use std::string for filenames. /** Write the document to a file. * @param filename * @param encoding If not provided, UTF-8 is used * @throws xmlpp::exception */ - void write_to_file(const Glib::ustring& filename, const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + void write_to_file(const std::string& filename, const ustring& encoding = ustring()); /** Write the document to a file. * The output is formatted by inserting whitespaces, which is easier to read for a human, @@ -166,14 +208,16 @@ class Document : NonCopyable * @param encoding If not provided, UTF-8 is used * @throws xmlpp::exception */ - void write_to_file_formatted(const Glib::ustring& filename, const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + void write_to_file_formatted(const std::string& filename, const ustring& encoding = ustring()); /** Write the document to the memory. * @param encoding If not provided, UTF-8 is used * @returns The written document. * @throws xmlpp::exception */ - Glib::ustring write_to_string(const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + ustring write_to_string(const ustring& encoding = ustring()); /** Write the document to the memory. * The output is formatted by inserting whitespaces, which is easier to read for a human, @@ -182,7 +226,8 @@ class Document : NonCopyable * @returns The written document. * @throws xmlpp::exception */ - Glib::ustring write_to_string_formatted(const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + ustring write_to_string_formatted(const ustring& encoding = ustring()); /** Write the document to a std::ostream. * @param output A reference to the stream in which the document will be written @@ -192,7 +237,8 @@ class Document : NonCopyable * @warning This method is much less efficient than write_to_string if you want to dump the * document to a buffer or the standard output. Writing to a fstream is almost as fast as write_to_file */ - void write_to_stream(std::ostream& output, const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + void write_to_stream(std::ostream& output, const ustring& encoding = ustring()); /** Write the document to a std::ostream. * The output is formatted by inserting whitespaces, which is easier to read for a human, @@ -203,7 +249,8 @@ class Document : NonCopyable * @throws xmlpp::internal_error * @warning See write_to_stream */ - void write_to_stream_formatted(std::ostream & output, const Glib::ustring& encoding = Glib::ustring()); + LIBXMLPP_API + void write_to_stream_formatted(std::ostream & output, const ustring& encoding = ustring()); /** Add an Entity declaration to the document. * @param name The name of the entity that will be used in an entity reference. @@ -214,9 +261,12 @@ class Document : NonCopyable * is the replacement value. * @throws xmlpp::internal_error */ - virtual void set_entity_declaration(const Glib::ustring& name, XmlEntityType type, - const Glib::ustring& publicId, const Glib::ustring& systemId, - const Glib::ustring& content); + LIBXMLPP_API + virtual void set_entity_declaration(const ustring& name, + XmlEntityType type, + const ustring& publicId, + const ustring& systemId, + const ustring& content); /** Perform XInclude substitution on the XML document. * XInclude substitution may both add and delete nodes in the document, @@ -226,34 +276,42 @@ class Document : NonCopyable * The type of a C++ wrapper can't change. The old wrapper is deleted, and a * new one is created if and when it's required.) * + * Parser::set_parser_options() and DomParser::set_xinclude_options() do not + * affect %Document::process_xinclude(). + * * @newin{2,36} * * @param generate_xinclude_nodes Generate XIncludeStart and XIncludeEnd nodes. + * @param fixup_base_uris Add or replace xml:base attributes in included element + * nodes, if necessary to preserve the target of relative URIs. * @returns The number of substitutions. * @throws xmlpp::exception */ - int process_xinclude(bool generate_xinclude_nodes = true); + LIBXMLPP_API + int process_xinclude(bool generate_xinclude_nodes = true, bool fixup_base_uris = true); ///Access the underlying libxml implementation. - _xmlDoc* cobj(); + LIBXMLPP_API _xmlDoc* cobj() noexcept; ///Access the underlying libxml implementation. - const _xmlDoc* cobj() const; + LIBXMLPP_API const _xmlDoc* cobj() const noexcept; protected: /** Retrieve an Entity. * The entity can be from an external subset or internally declared. * @param name The name of the entity to get. - * @returns A pointer to the libxml2 entity structure, or 0 if not found. + * @returns A pointer to the libxml2 entity structure, or nullptr if not found. */ - _xmlEntity* get_entity(const Glib::ustring& name); + LIBXMLPP_API + _xmlEntity* get_entity(const ustring& name); private: - //TODO: Remove virtuals when we can break ABI. - - virtual void do_write_to_file(const Glib::ustring& filename, const Glib::ustring& encoding, bool format); - virtual Glib::ustring do_write_to_string(const Glib::ustring& encoding, bool format); - virtual void do_write_to_stream(std::ostream& output, const Glib::ustring& encoding, bool format); + LIBXMLPP_API + void do_write_to_file(const std::string& filename, const ustring& encoding, bool format); + LIBXMLPP_API + ustring do_write_to_string(const ustring& encoding, bool format); + LIBXMLPP_API + void do_write_to_stream(std::ostream& output, const ustring& encoding, bool format); static Init init_; diff --git a/libxml++/dtd.cc b/libxml++/dtd.cc index 13703a7f..dda2a41c 100644 --- a/libxml++/dtd.cc +++ b/libxml++/dtd.cc @@ -5,45 +5,168 @@ */ #include +#include +#include -#include +#include + +#include namespace xmlpp { - -Dtd::Dtd(_xmlDtd* dtd) -: impl_(dtd) + +struct Dtd::Impl +{ + Impl() noexcept : dtd(nullptr), is_dtd_owner(false) {} + + _xmlDtd* dtd; + bool is_dtd_owner; +}; + +Dtd::Dtd() +: pimpl_(new Impl) +{ +} + +Dtd::Dtd(_xmlDtd* dtd, bool take_ownership) +: pimpl_(new Impl) +{ + pimpl_->dtd = dtd; + if (dtd) + { + pimpl_->dtd->_private = this; + pimpl_->is_dtd_owner = take_ownership; + } +} + +Dtd::Dtd(const std::string& filename) +: pimpl_(new Impl) +{ + parse_subset("", filename); +} + +Dtd::Dtd(const ustring& external, const ustring& system) +: pimpl_(new Impl) { - dtd->_private = this; + parse_subset(external, system); } Dtd::~Dtd() -{ +{ + release_underlying(); +} + +void Dtd::parse_file(const std::string& filename) +{ + parse_subset("", filename); +} + +void Dtd::parse_subset(const ustring& external, const ustring& system) +{ + release_underlying(); // Free any existing dtd. + xmlResetLastError(); + + auto dtd = xmlParseDTD( + external.empty() ? nullptr : (const xmlChar*)external.c_str(), + system.empty() ? nullptr : (const xmlChar*)system.c_str()); + + if (!dtd) + { + throw parse_error("Dtd could not be parsed.\n" + format_xml_error()); + } + + pimpl_->dtd = dtd; + pimpl_->dtd->_private = this; + pimpl_->is_dtd_owner = true; +} + +void Dtd::parse_memory(const ustring& contents) +{ + // Prepare an istream with buffer + std::istringstream is(contents); + + parse_stream(is); +} + +void Dtd::parse_stream(std::istream& in) +{ + release_underlying(); // Free any existing dtd. + xmlResetLastError(); + + IStreamParserInputBuffer ibuff(in); + + auto dtd = xmlIOParseDTD(nullptr, ibuff.cobj(), XML_CHAR_ENCODING_UTF8); + + if (!dtd) + { + throw parse_error("Dtd could not be parsed.\n" + format_xml_error()); + } + + pimpl_->dtd = dtd; + pimpl_->dtd->_private = this; + pimpl_->is_dtd_owner = true; +} + +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Dtd::get_name() const +{ + return (pimpl_->dtd && pimpl_->dtd->name) ? (const char*)pimpl_->dtd->name : ""; +} + +ustring Dtd::get_external_id() const +{ + return (pimpl_->dtd && pimpl_->dtd->ExternalID) ? (const char*)pimpl_->dtd->ExternalID : ""; +} + +ustring Dtd::get_system_id() const +{ + return (pimpl_->dtd && pimpl_->dtd->SystemID) ? (const char*)pimpl_->dtd->SystemID : ""; +} +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional Dtd::get_name2() const +{ + if (!(pimpl_->dtd && pimpl_->dtd->name)) + return {}; + return (const char*)pimpl_->dtd->name; } -Glib::ustring Dtd::get_name() const +std::optional Dtd::get_external_id2() const { - return (char*)impl_->name; + if (!(pimpl_->dtd && pimpl_->dtd->ExternalID)) + return {}; + return (const char*)pimpl_->dtd->ExternalID; } -Glib::ustring Dtd::get_external_id() const +std::optional Dtd::get_system_id2() const { - return (char*)impl_->ExternalID; + if (!(pimpl_->dtd && pimpl_->dtd->SystemID)) + return {}; + return (const char*)pimpl_->dtd->SystemID; } -Glib::ustring Dtd::get_system_id() const +_xmlDtd* Dtd::cobj() noexcept { - return (char*)impl_->SystemID; + return pimpl_->dtd; } -_xmlDtd* Dtd::cobj() +const _xmlDtd* Dtd::cobj() const noexcept { - return impl_; + return pimpl_->dtd; } -const _xmlDtd* Dtd::cobj() const +void Dtd::release_underlying() { - return impl_; + if (pimpl_->dtd) + { + pimpl_->dtd->_private = nullptr; + if (pimpl_->is_dtd_owner) + { + xmlFreeDtd(pimpl_->dtd); + pimpl_->is_dtd_owner = false; + } + pimpl_->dtd = nullptr; + } } } //namespace xmlpp diff --git a/libxml++/dtd.h b/libxml++/dtd.h index 6198072e..258c7c3f 100644 --- a/libxml++/dtd.h +++ b/libxml++/dtd.h @@ -7,46 +7,171 @@ #ifndef __LIBXMLPP_DTD_H #define __LIBXMLPP_DTD_H -#include -#include -#include +#include +#include "libxml++/ustring.h" +#include +#include +#include // std::unique_ptr #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { struct _xmlDtd; } -#endif //DOXYGEN_SHOULD_SKIP_THIS4 +#endif //DOXYGEN_SHOULD_SKIP_THIS namespace xmlpp { -/** Represents XML DTDs. - * +//TODO: Derive from Node? +// See https://bugzilla.gnome.org/show_bug.cgi?id=754673#c8 for an explanation +// why it has not been done in libxml++ 3.0. +/** Represents an XML DTD for validating XML files. + * DTD = %Document Type Definition */ -class Dtd //TODO: Derive from Node? +class Dtd : public NonCopyable { public: - Dtd(_xmlDtd* dtd); - ~Dtd(); + LIBXMLPP_API Dtd(); + + /** Create a Dtd from the underlying libxml DTD element. + * @param dtd A pointer to the libxml DTD element. + * @param take_ownership If true, this Dtd instance takes ownership of + * the libxml DTD element. The caller must not delete it.
+ * If false, this Dtd does not take ownership of the libxml + * DTD element. The caller must guarantee that the libxml DTD element + * exists as long as this Dtd keeps a pointer to it. The caller is + * responsible for deleting the libxml DTD element when it's no longer + * needed, unless it belongs to a Document, in which case it's deleted + * when the Document is deleted. + */ + LIBXMLPP_API + explicit Dtd(_xmlDtd* dtd, bool take_ownership = false); + + /** Create a Dtd and parse an external subset (DTD file) immediately. + * + * @newin{3,0} + * + * @param filename The URL of the DTD. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + explicit Dtd(const std::string& filename); + + /** Create a Dtd and parse an external subset (DTD file) immediately. + * + * @newin{3,0} + * + * @param external The external ID of the DTD. + * @param system The URL of the DTD. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + Dtd(const ustring& external, const ustring& system); + + LIBXMLPP_API ~Dtd() override; + + /** Parse an external subset (DTD file). + * If another DTD has been parsed before, that DTD is replaced by the new one + * (deleted if this Dtd owns it). + * + * @newin{3,0} + * + * @param filename The URL of the DTD. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + void parse_file(const std::string& filename); + + /** Parse an external subset (DTD file). + * If another DTD has been parsed before, that DTD is replaced by the new one + * (deleted if this Dtd owns it). + * + * @newin{3,0} + * + * @param external The external ID of the DTD. + * @param system The URL of the DTD. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + void parse_subset(const ustring& external, const ustring& system); + + /** Parse a DTD from a string. + * If another DTD has been parsed before, that DTD is replaced by the new one + * (deleted if this Dtd owns it). + * + * @newin{3,0} + * + * @param contents The DTD as a string. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + void parse_memory(const ustring& contents); + + /** Parse a DTD from a stream. + * If another DTD has been parsed before, that DTD is replaced by the new one + * (deleted if this Dtd owns it). + * + * @newin{3,0} + * + * @param in The stream. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API void parse_stream(std::istream& in); + +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Get the name of the DTD. + * @return The name of the DTD. + * @deprecated 5.6: Use get_name2() instead. + */ + LIBXMLPP_API ustring get_name() const; + + /** Get the external identifier for PUBLIC DTD. + * @return The external identifier for PUBLIC DTD. + * @deprecated 5.6: Use get_external_id2() instead. + */ + LIBXMLPP_API ustring get_external_id() const; + + /** Get the URI for a SYSTEM or PUBLIC DTD. + * @return The URI for a SYSTEM or PUBLIC DTD. + * @deprecated 5.6: Use get_system_id2() instead. + */ + LIBXMLPP_API ustring get_system_id() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the name of the DTD. + * @return The name of the DTD, if any, else no value. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_name2() const; + + /** Get the external identifier for PUBLIC DTD. + * @return The external identifier for PUBLIC DTD, if any, else no value. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_external_id2() const; + + /** Get the URI for a SYSTEM or PUBLIC DTD. + * @return The URI for a SYSTEM or PUBLIC DTD, if any, else no value. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_system_id2() const; - Glib::ustring get_name() const; - Glib::ustring get_external_id() const; - Glib::ustring get_system_id() const; - /** Access the underlying libxml implementation. */ - _xmlDtd* cobj(); + LIBXMLPP_API _xmlDtd* cobj() noexcept; /** Access the underlying libxml implementation. */ - const _xmlDtd* cobj() const; + LIBXMLPP_API const _xmlDtd* cobj() const noexcept; + +protected: + LIBXMLPP_API void release_underlying(); + private: - _xmlDtd* impl_; + struct Impl; + std::unique_ptr pimpl_; }; } // namespace xmlpp #endif //__LIBXMLPP_DTD_H - - - diff --git a/libxml++/exceptions/exception.cc b/libxml++/exceptions/exception.cc index 89b5a4d9..d2ed4943 100644 --- a/libxml++/exceptions/exception.cc +++ b/libxml++/exceptions/exception.cc @@ -1,10 +1,12 @@ #include "exception.h" #include #include +#include +#include namespace xmlpp { - -exception::exception(const Glib::ustring& message) + +exception::exception(const ustring& message) : message_(message) { } @@ -17,17 +19,17 @@ const char* exception::what() const noexcept return message_.c_str(); } -void exception::Raise() const +void exception::raise() const { throw *this; } -exception * exception::Clone() const +exception* exception::clone() const { return new exception(*this); } -Glib::ustring format_xml_error(const _xmlError* error) +ustring format_xml_error(const _xmlError* error) { if (!error) error = xmlGetLastError(); @@ -35,7 +37,7 @@ Glib::ustring format_xml_error(const _xmlError* error) if (!error || error->code == XML_ERR_OK) return ""; // No error - Glib::ustring str; + ustring str; if (error->file && *error->file != '\0') { @@ -45,9 +47,9 @@ Glib::ustring format_xml_error(const _xmlError* error) if (error->line > 0) { - str += (str.empty() ? "Line " : ", line ") + Glib::ustring::format(error->line); + str += (str.empty() ? "Line " : ", line ") + std::to_string(error->line); if (error->int2 > 0) - str += ", column " + Glib::ustring::format(error->int2); + str += ", column " + std::to_string(error->int2); } const bool two_lines = !str.empty(); @@ -75,7 +77,7 @@ Glib::ustring format_xml_error(const _xmlError* error) if (error->message && *error->message != '\0') str += error->message; else - str += "Error code " + Glib::ustring::format(error->code); + str += "Error code " + std::to_string(error->code); // If the string does not end with end-of-line, append an end-of-line. if (*str.rbegin() != '\n') @@ -84,7 +86,7 @@ Glib::ustring format_xml_error(const _xmlError* error) return str; } -Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context) +ustring format_xml_parser_error(const _xmlParserCtxt* parser_context) { if (!parser_context) return "Error. xmlpp::format_xml_parser_error() called with parser_context == nullptr\n"; @@ -94,7 +96,7 @@ Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context) if (!error) return ""; // No error - Glib::ustring str; + ustring str; if (!parser_context->wellFormed) str += "Document not well-formed.\n"; @@ -102,5 +104,22 @@ Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context) return str + format_xml_error(error); } -} //namespace xmlpp +ustring format_printf_message(const char* fmt, va_list args) +{ + // This code was inspired by the example at + // http://en.cppreference.com/w/cpp/io/c/vfprintf + va_list args2; + va_copy(args2, args); + // Number of characters (bytes) in the resulting string; + // error, if < 0. + const int nchar = std::vsnprintf(nullptr, 0, fmt, args2); + va_end(args2); + if (nchar < 0) + return "Error code from std::vsnprintf = " + std::to_string(nchar); + + std::vector buf(nchar+1); + std::vsnprintf(buf.data(), buf.size(), fmt, args); + return ustring(buf.data()); +} +} //namespace xmlpp diff --git a/libxml++/exceptions/exception.h b/libxml++/exceptions/exception.h index dffbe5a0..b86269b5 100644 --- a/libxml++/exceptions/exception.h +++ b/libxml++/exceptions/exception.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* exception.h * * Copyright (C) 2002 The libxml++ development team @@ -15,15 +13,15 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_EXCEPTION_H #define __LIBXMLPP_EXCEPTION_H #include -#include +#include // va_list +#include "libxml++/ustring.h" #include @@ -37,32 +35,33 @@ namespace xmlpp /** Base class for all xmlpp exceptions. */ -class LIBXMLPP_API exception: public std::exception +class LIBXMLPP_VISIBILITY_DEFAULT exception : public std::exception { public: - explicit exception(const Glib::ustring& message); - ~exception() noexcept override; + LIBXMLPP_MEMBER_METHOD + explicit exception(const ustring& message); + LIBXMLPP_MEMBER_METHOD ~exception() noexcept override; - const char* what() const noexcept override; + LIBXMLPP_MEMBER_METHOD const char* what() const noexcept override; - //TODO: Use lower-case names when we can break ABI? - virtual void Raise() const; - virtual exception * Clone() const; + LIBXMLPP_MEMBER_METHOD virtual void raise() const; + LIBXMLPP_MEMBER_METHOD virtual exception* clone() const; private: - Glib::ustring message_; + ustring message_; }; /** Format an _xmlError struct into a text string, suitable for printing. * * @newin{2,36} * - * @param error Pointer to an _xmlError struct or 0. If 0, - * the error returned by xmlGetLastError() is used. + * @param error Pointer to an _xmlError struct or nullptr. + * If nullptr, the error returned by xmlGetLastError() is used. * @returns A formatted text string. If the error struct does not contain an * error (error->code == XML_ERR_OK), an empty string is returned. */ -Glib::ustring format_xml_error(const _xmlError* error = nullptr); +LIBXMLPP_API +ustring format_xml_error(const _xmlError* error = nullptr); /** Format a parser error into a text string, suitable for printing. * @@ -73,7 +72,30 @@ Glib::ustring format_xml_error(const _xmlError* error = nullptr); * error (parser_context->lastError.code == XML_ERR_OK), an empty * string is returned. */ -Glib::ustring format_xml_parser_error(const _xmlParserCtxt* parser_context); +LIBXMLPP_API +ustring format_xml_parser_error(const _xmlParserCtxt* parser_context); + +/** Format a message from a function with C-style variadic parameters. + * + * Helper function that formats a message supplied in the form of a printf-style + * format specification and zero or more ... parameters. + * + * @code + * // Typical call: + * void f(const char* fmt, ...) + * { + * va_list args; + * va_start(args, fmt); + * ustring msg = xmlpp::format_printf_message(fmt, args); + * va_end(args); + * // ... + * } + * @endcode + * + * @newin{3,0} + */ +LIBXMLPP_API +ustring format_printf_message(const char* fmt, va_list args); } // namespace xmlpp diff --git a/libxml++/exceptions/internal_error.cc b/libxml++/exceptions/internal_error.cc index 13f6392c..215c2d9e 100644 --- a/libxml++/exceptions/internal_error.cc +++ b/libxml++/exceptions/internal_error.cc @@ -1,9 +1,8 @@ #include "internal_error.h" - namespace xmlpp { -internal_error::internal_error(const Glib::ustring& message) +internal_error::internal_error(const ustring& message) : exception(message) { } @@ -11,16 +10,14 @@ internal_error::internal_error(const Glib::ustring& message) internal_error::~internal_error() noexcept {} -void internal_error::Raise() const +void internal_error::raise() const { throw *this; } -exception * internal_error::Clone() const +exception* internal_error::clone() const { return new internal_error(*this); } } //namespace xmlpp - - diff --git a/libxml++/exceptions/internal_error.h b/libxml++/exceptions/internal_error.h index 887dd65b..0126247d 100644 --- a/libxml++/exceptions/internal_error.h +++ b/libxml++/exceptions/internal_error.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* internal_error.h * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_INTERNAL_ERROR_H @@ -24,19 +21,17 @@ #include -#include -#include - namespace xmlpp { - -class internal_error: public exception + +class internal_error : public exception { public: - explicit internal_error(const Glib::ustring& message); - ~internal_error() noexcept override; + LIBXMLPP_API + explicit internal_error(const ustring& message); + LIBXMLPP_API ~internal_error() noexcept override; - void Raise() const override; - exception * Clone() const override; + LIBXMLPP_API void raise() const override; + LIBXMLPP_API exception* clone() const override; }; } // namespace xmlpp diff --git a/libxml++/exceptions/parse_error.cc b/libxml++/exceptions/parse_error.cc index b9c19877..5708ccf0 100644 --- a/libxml++/exceptions/parse_error.cc +++ b/libxml++/exceptions/parse_error.cc @@ -2,7 +2,7 @@ namespace xmlpp { -parse_error::parse_error(const Glib::ustring& message) +parse_error::parse_error(const ustring& message) : exception(message) { } @@ -10,15 +10,14 @@ parse_error::parse_error(const Glib::ustring& message) parse_error::~parse_error() noexcept {} -void parse_error::Raise() const +void parse_error::raise() const { throw *this; } -exception* parse_error::Clone() const +exception* parse_error::clone() const { return new parse_error(*this); } } //namespace xmlpp - diff --git a/libxml++/exceptions/parse_error.h b/libxml++/exceptions/parse_error.h index 12c80998..c4185fc0 100644 --- a/libxml++/exceptions/parse_error.h +++ b/libxml++/exceptions/parse_error.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* parse_error.h * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_PARSE_ERROR_H @@ -24,22 +21,20 @@ #include -#include -#include - namespace xmlpp { /** This exception will be thrown when the parser encounters an error in the XML document. - */ -class parse_error: public exception + */ +class parse_error : public exception { public: - explicit parse_error(const Glib::ustring& message); - ~parse_error() noexcept override; + LIBXMLPP_API + explicit parse_error(const ustring& message); + LIBXMLPP_API ~parse_error() noexcept override; - void Raise() const override; - exception* Clone() const override; + LIBXMLPP_API void raise() const override; + LIBXMLPP_API exception* clone() const override; }; } // namespace xmlpp diff --git a/libxml++/exceptions/validity_error.cc b/libxml++/exceptions/validity_error.cc index d34332fc..537fe027 100644 --- a/libxml++/exceptions/validity_error.cc +++ b/libxml++/exceptions/validity_error.cc @@ -2,7 +2,7 @@ namespace xmlpp { -validity_error::validity_error(const Glib::ustring& message) +validity_error::validity_error(const ustring& message) : parse_error(message) { } @@ -10,15 +10,14 @@ validity_error::validity_error(const Glib::ustring& message) validity_error::~validity_error() noexcept {} -void validity_error::Raise() const +void validity_error::raise() const { throw *this; } -exception* validity_error::Clone() const +exception* validity_error::clone() const { return new validity_error(*this); } } //namespace xmlpp - diff --git a/libxml++/exceptions/validity_error.h b/libxml++/exceptions/validity_error.h index 513d0e1b..1a1ab0ad 100644 --- a/libxml++/exceptions/validity_error.h +++ b/libxml++/exceptions/validity_error.h @@ -1,5 +1,3 @@ -// -*- C++ -*- - /* validity_error.h * * Copyright (C) 2002 The libxml++ development team @@ -15,8 +13,7 @@ * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_VALIDITY_ERROR_H @@ -29,14 +26,15 @@ namespace xmlpp /** This exception will be thrown when the parser encounters a validity error in the XML document. */ -class validity_error: public parse_error +class validity_error : public parse_error { public: - explicit validity_error(const Glib::ustring& message); - ~validity_error() noexcept override; + LIBXMLPP_API + explicit validity_error(const ustring& message); + LIBXMLPP_API ~validity_error() noexcept override; - void Raise() const override; - exception* Clone() const override; + LIBXMLPP_API void raise() const override; + LIBXMLPP_API exception* clone() const override; }; } // namespace xmlpp diff --git a/libxml++/exceptions/wrapped_exception.cc b/libxml++/exceptions/wrapped_exception.cc index 8799e741..6044a7e1 100644 --- a/libxml++/exceptions/wrapped_exception.cc +++ b/libxml++/exceptions/wrapped_exception.cc @@ -11,8 +11,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ #include "wrapped_exception.h" @@ -20,8 +19,10 @@ namespace xmlpp { +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR + wrapped_exception::wrapped_exception(std::exception_ptr exception_ptr) - : exception("Wrapped exception"), exception_ptr_(exception_ptr) + : exception("Wrapped exception"), exception_ptr_(std::move(exception_ptr)) { } @@ -29,14 +30,16 @@ wrapped_exception::~wrapped_exception() noexcept { } -void wrapped_exception::Raise() const +void wrapped_exception::raise() const { std::rethrow_exception(exception_ptr_); } -exception* wrapped_exception::Clone() const +exception* wrapped_exception::clone() const { return new wrapped_exception(exception_ptr_); } +#endif // LIBXMLXX_HAVE_EXCEPTION_PTR + } // namespace xmlpp diff --git a/libxml++/exceptions/wrapped_exception.h b/libxml++/exceptions/wrapped_exception.h index 6fa7baca..f523e319 100644 --- a/libxml++/exceptions/wrapped_exception.h +++ b/libxml++/exceptions/wrapped_exception.h @@ -11,8 +11,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ #ifndef __LIBXMLPP_WRAPPED_EXCEPTION_H @@ -21,36 +20,37 @@ #include #include +#include namespace xmlpp { -#ifndef DOXYGEN_SHOULD_SKIP_THIS -//TODO: At the next ABI break, consider changing -// exception* exception_; -// to -// std::exception_ptr exception_ptr_; -// in xmlpp::Parser and xmlpp::Validator, and removing xmlpp::wrapped_exception. +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR +#ifndef DOXYGEN_SHOULD_SKIP_THIS /** Helper class for propagating an exception through C code. * Should not be used by applications. + * Does not exist in systems that don't support std::exception_ptr. * * @newin{2,40} */ class wrapped_exception : public exception { public: + LIBXMLPP_API explicit wrapped_exception(std::exception_ptr exception_ptr); - ~wrapped_exception() noexcept override; + LIBXMLPP_API ~wrapped_exception() noexcept override; - void Raise() const override; - exception* Clone() const override; + LIBXMLPP_API void raise() const override; + LIBXMLPP_API exception* clone() const override; private: std::exception_ptr exception_ptr_; }; #endif //DOXYGEN_SHOULD_SKIP_THIS +#endif // LIBXMLXX_HAVE_EXCEPTION_PTR + } // namespace xmlpp #endif // __LIBXMLPP_WRAPPED_EXCEPTION_H diff --git a/libxml++/filelist.am b/libxml++/filelist.am index 68a119db..70fdd270 100644 --- a/libxml++/filelist.am +++ b/libxml++/filelist.am @@ -9,8 +9,8 @@ h_root_sources_public = \ keepblanks.h \ noncopyable.h \ relaxngschema.h \ - schema.h \ schemabase.h \ + ustring.h \ xsdschema.h h_exceptions_sources_public = \ exceptions/exception.h \ @@ -43,7 +43,6 @@ h_parsers_sources_public = \ h_validators_sources_public = \ validators/dtdvalidator.h \ validators/relaxngvalidator.h \ - validators/schemavalidator.h \ validators/schemavalidatorbase.h \ validators/validator.h \ validators/xsdvalidator.h diff --git a/libxml++/io/istreamparserinputbuffer.h b/libxml++/io/istreamparserinputbuffer.h index 9140fb09..706f917d 100644 --- a/libxml++/io/istreamparserinputbuffer.h +++ b/libxml++/io/istreamparserinputbuffer.h @@ -16,7 +16,7 @@ namespace xmlpp { - class IStreamParserInputBuffer: public ParserInputBuffer + class LIBXMLPP_API IStreamParserInputBuffer: public ParserInputBuffer { public: /** diff --git a/libxml++/io/ostreamoutputbuffer.cc b/libxml++/io/ostreamoutputbuffer.cc index b23a8b61..512b05fe 100644 --- a/libxml++/io/ostreamoutputbuffer.cc +++ b/libxml++/io/ostreamoutputbuffer.cc @@ -13,7 +13,7 @@ namespace xmlpp { OStreamOutputBuffer::OStreamOutputBuffer( std::ostream & output, - const Glib::ustring& encoding) + const ustring& encoding) : OutputBuffer(encoding), output_(output) { } @@ -21,7 +21,7 @@ namespace xmlpp OStreamOutputBuffer::~OStreamOutputBuffer() { } - + bool OStreamOutputBuffer::do_write( const char * buffer, int len) diff --git a/libxml++/io/ostreamoutputbuffer.h b/libxml++/io/ostreamoutputbuffer.h index bef47bc8..516d8b6e 100644 --- a/libxml++/io/ostreamoutputbuffer.h +++ b/libxml++/io/ostreamoutputbuffer.h @@ -18,7 +18,7 @@ namespace xmlpp { /** An OutputBuffer implementation that send datas to a std::ostream. */ - class OStreamOutputBuffer: public OutputBuffer + class LIBXMLPP_API OStreamOutputBuffer: public OutputBuffer { public: /** @@ -26,7 +26,7 @@ namespace xmlpp * @param encoding Charset in which data will be encoded before being * sent to the stream */ - OStreamOutputBuffer(std::ostream& output, const Glib::ustring& encoding = Glib::ustring()); + OStreamOutputBuffer(std::ostream& output, const ustring& encoding = ustring()); ~OStreamOutputBuffer() override; private: diff --git a/libxml++/io/outputbuffer.cc b/libxml++/io/outputbuffer.cc index c454417d..a0b4d663 100644 --- a/libxml++/io/outputbuffer.cc +++ b/libxml++/io/outputbuffer.cc @@ -32,7 +32,7 @@ namespace xmlpp OutputBuffer::OutputBuffer( - const Glib::ustring& encoding) + const ustring& encoding) { // we got to initialise the char encoding handler // The code is almost cut/paste from xmlSaveFormatFileEnc @@ -93,12 +93,12 @@ namespace xmlpp return true; } - _xmlOutputBuffer* OutputBuffer::cobj() + _xmlOutputBuffer* OutputBuffer::cobj() noexcept { return impl_; } - const _xmlOutputBuffer* OutputBuffer::cobj() const + const _xmlOutputBuffer* OutputBuffer::cobj() const noexcept { return impl_; } diff --git a/libxml++/io/outputbuffer.h b/libxml++/io/outputbuffer.h index 77115558..049ef610 100644 --- a/libxml++/io/outputbuffer.h +++ b/libxml++/io/outputbuffer.h @@ -10,7 +10,7 @@ #ifndef __LIBXMLPP_OUTPUTBUFFER_H #define __LIBXMLPP_OUTPUTBUFFER_H -#include +#include "libxml++/ustring.h" #include #ifndef DOXYGEN_SHOULD_SKIP_THIS @@ -22,7 +22,7 @@ extern "C" namespace xmlpp { - struct OutputBufferCallback; + struct LIBXMLPP_API OutputBufferCallback; /** Base class for xmlOutputBuffer wrapper * @@ -30,7 +30,7 @@ namespace xmlpp * A child class has to override do_write(), and possibly * do_close() if some actions are required before buffer closing. */ - class OutputBuffer: public NonCopyable + class LIBXMLPP_API OutputBuffer: public NonCopyable { public: /** @@ -40,17 +40,17 @@ namespace xmlpp * @warning The encoding is done by libxml. As a consequence, libxml must * have a translator to the target encoding. */ - OutputBuffer(const Glib::ustring& encoding = Glib::ustring()); + OutputBuffer(const ustring& encoding = ustring()); ~OutputBuffer() override; public: /** gives an access to the underlying libxml structure to the children */ - _xmlOutputBuffer* cobj(); + _xmlOutputBuffer* cobj() noexcept; /** gives an access to the underlying libxml structure to the children */ - const _xmlOutputBuffer* cobj() const; + const _xmlOutputBuffer* cobj() const noexcept; private: bool on_write(const char * buffer, int len); diff --git a/libxml++/io/parserinputbuffer.cc b/libxml++/io/parserinputbuffer.cc index 891b5acd..24cd2a87 100644 --- a/libxml++/io/parserinputbuffer.cc +++ b/libxml++/io/parserinputbuffer.cc @@ -1,4 +1,4 @@ -/* document.h +/* parserinputbuffer.cc * this file is part of libxml++ * * copyright (C) 2003 by libxml++ developer's team @@ -39,7 +39,7 @@ namespace xmlpp &ParserInputBufferCallback::on_close, static_cast(this), XML_CHAR_ENCODING_NONE); - if(impl_ == 0) + if (!impl_) { throw internal_error("Cannot initialise underlying xmlParserInputBuffer"); } @@ -54,7 +54,7 @@ namespace xmlpp bool result = do_close(); // the underlying structure is being freed by libxml, the pointer will soon be // invalid. - impl_ = 0; + impl_ = nullptr; return result; } @@ -71,12 +71,12 @@ namespace xmlpp return true; } - _xmlParserInputBuffer* ParserInputBuffer::cobj() + _xmlParserInputBuffer* ParserInputBuffer::cobj() noexcept { return impl_; } - const _xmlParserInputBuffer* ParserInputBuffer::cobj() const + const _xmlParserInputBuffer* ParserInputBuffer::cobj() const noexcept { return impl_; } diff --git a/libxml++/io/parserinputbuffer.h b/libxml++/io/parserinputbuffer.h index a5847087..55c52325 100644 --- a/libxml++/io/parserinputbuffer.h +++ b/libxml++/io/parserinputbuffer.h @@ -20,7 +20,7 @@ extern "C" namespace xmlpp { - struct ParserInputBufferCallback; + struct LIBXMLPP_API ParserInputBufferCallback; /** Base class for xmlParserInputBuffer wrapper * @@ -28,7 +28,7 @@ namespace xmlpp * A child class has to override do_write(), and possibly * do_close() if some actions are required before buffer closing. */ - class ParserInputBuffer: public NonCopyable + class LIBXMLPP_API ParserInputBuffer: public NonCopyable { public: ParserInputBuffer(); @@ -37,11 +37,11 @@ namespace xmlpp public: /** gives an access to the underlying libxml structure to the children */ - _xmlParserInputBuffer* cobj(); + _xmlParserInputBuffer* cobj() noexcept; /** gives an access to the underlying libxml structure to the children */ - const _xmlParserInputBuffer* cobj() const; + const _xmlParserInputBuffer* cobj() const noexcept; private: int on_read(char * buffer, int len); diff --git a/libxml++/keepblanks.cc b/libxml++/keepblanks.cc index a91f2a6a..f00660f6 100644 --- a/libxml++/keepblanks.cc +++ b/libxml++/keepblanks.cc @@ -5,27 +5,29 @@ * included with libxml++ as the file COPYING. */ -#include +// xmlKeepBlanksDefault() is deprecated since libxml2 2.12.0. +// xmlIndentTreeOutput is deprecated since libxml2 2.15.0. +// Ignore deprecations here. +#define XML_DEPRECATED +#include #include namespace xmlpp { - #if _MSC_VER == 1200 // detect MSVC 6.0 const bool KeepBlanks::Default = true; #endif - - KeepBlanks::KeepBlanks(bool value) + + KeepBlanks::KeepBlanks(bool value) noexcept { oldIndentTreeOutput_ = xmlIndentTreeOutput; oldKeepBlanksDefault_ = xmlKeepBlanksDefault( value?1:0 ); } - KeepBlanks::~KeepBlanks() + KeepBlanks::~KeepBlanks() noexcept { xmlKeepBlanksDefault(oldKeepBlanksDefault_); xmlIndentTreeOutput = oldIndentTreeOutput_; } } - diff --git a/libxml++/keepblanks.h b/libxml++/keepblanks.h index a2002e27..40bfed59 100644 --- a/libxml++/keepblanks.h +++ b/libxml++/keepblanks.h @@ -8,31 +8,26 @@ #ifndef __LIBXMLPP_KEEPBLANKS_H #define __LIBXMLPP_KEEPBLANKS_H +#include + namespace xmlpp { - - /** - * This class set KeepBlanksDefault and IndentTreeOutput of libxmlpp - * and restore their initial value in its destructor. As a consequence + /** This class sets KeepBlanksDefault and IndentTreeOutput of libxmlpp + * and restores their initial values in its destructor. As a consequence * the wanted setting is kept during instance lifetime. */ - class KeepBlanks { + class LIBXMLPP_API KeepBlanks { public: -#if _MSC_VER == 1200 // detect MSVC 6.0 - static const bool Default; -#else static const bool Default = true; -#endif public: - KeepBlanks(bool value); - ~KeepBlanks(); + KeepBlanks(bool value) noexcept; + ~KeepBlanks() noexcept; private: int oldKeepBlanksDefault_; int oldIndentTreeOutput_; }; - } #endif // __LIBXMLPP_KEEPBLANKS_H diff --git a/libxml++/libxml++.h b/libxml++/libxml++.h index 1338b48c..bb599527 100644 --- a/libxml++/libxml++.h +++ b/libxml++/libxml++.h @@ -14,7 +14,8 @@ * libxml++ is a C++ wrapper for the libxml2 XML parser and builder library. It presents a * simple C++-like API that can achieve common tasks with less code. * - * See also the libxml++ Tutorial and the libxml++ website. + * See also the libxml++ Tutorial + * and the libxml++ website. * * @section features Features * @@ -33,12 +34,14 @@ * * If your source file is @c program.cc, you can compile it with: * @code - * g++ program.cc -o program `pkg-config --cflags --libs libxml++-2.6` + * g++ program.cc -o program `pkg-config --cflags --libs libxml++-5.0` * @endcode + * If your version of g++ is not C++17-compliant be default, + * add the @c -std=c++17 option. * * Alternatively, if using autoconf, use the following in @c configure.ac: * @code - * PKG_CHECK_MODULES([LIBXMLXX], [libxml++-2.6]) + * PKG_CHECK_MODULES([LIBXMLXX], [libxml++-5.0]) * @endcode * Then use the generated @c LIBXMLXX_CFLAGS and @c LIBXMLXX_LIBS variables in * the project @c Makefile.am files. For example: @@ -71,7 +74,7 @@ #include #include #include -#include #include +#include #endif //__LIBXMLCPP_H diff --git a/libxml++/meson.build b/libxml++/meson.build new file mode 100644 index 00000000..eddb58e7 --- /dev/null +++ b/libxml++/meson.build @@ -0,0 +1,155 @@ +# libxml++ + +# Input: xmlxx_build_dep, xmlxx_pcname, xmlxx_libversion, xmlxx_api_version, +# install_includedir, xmlxx_rc, xmlxx_libname, macos_darwin_versions, +# xmlxx_pc_requires, libxml2_lib_pkgconfig +# Output: source_h_files, xmlxx_own_dep + +# There are no built source files in libxml++-5.0. + +source_h_files = [] +source_cc_files = [] + +xmlxx_base_h_cc_files = [ + 'attribute', + 'attributedeclaration', + 'attributenode', + 'document', + 'dtd', + 'keepblanks', + 'noncopyable', + 'relaxngschema', + 'schemabase', + 'ustring', + 'xsdschema', +] + +xmlxx_subdir_h_cc_files = [ +# [ dir-name, [files]] + ['exceptions', [ + 'exception', + 'parse_error', + 'validity_error', + 'internal_error', + 'wrapped_exception', + ]], + ['io', [ + 'istreamparserinputbuffer', + 'outputbuffer', + 'ostreamoutputbuffer', + 'parserinputbuffer', + ]], + ['nodes', [ + 'cdatanode', + 'commentnode', + 'contentnode', + 'element', + 'entitydeclaration', + 'entityreference', + 'node', + 'processinginstructionnode', + 'textnode', + 'xincludeend', + 'xincludestart', + ]], + ['parsers', [ + 'parser', + 'saxparser', + 'domparser', + 'textreader', + ]], + ['validators', [ + 'dtdvalidator', + 'relaxngvalidator', + 'schemavalidatorbase', + 'validator', + 'xsdvalidator', + ]], +] + +foreach f : xmlxx_base_h_cc_files + source_h_files += f + '.h' + source_cc_files += f + '.cc' +endforeach + +install_headers('libxml++.h', subdir: xmlxx_pcname / 'libxml++') +install_headers(source_h_files, subdir: xmlxx_pcname / 'libxml++') + +foreach dir_files : xmlxx_subdir_h_cc_files + dir = dir_files[0] + subdir_h_files = [] + foreach f : dir_files[1] + subdir_h_files += dir / f + '.h' + source_cc_files += dir / f + '.cc' + endforeach + source_h_files += subdir_h_files + install_headers(subdir_h_files, subdir: xmlxx_pcname / 'libxml++' / dir) +endforeach + +xmlxx_cpp_args = [ '-DLIBXMLPP_BUILD=1' ] + +# Make sure we are exporting the symbols from the DLL +if is_msvc and get_option('default_library') != 'static' + xmlxx_cpp_args += ['-D_WINDLL'] +endif + +xmlxx_all_deps = [xmlxx_build_dep] + +extra_xmlxx_objects = [] + +# Build the .rc file for Windows builds and link to it +if host_machine.system() == 'windows' + windows = import('windows') + xmlxx_res = windows.compile_resources(xmlxx_rc) + extra_xmlxx_objects += xmlxx_res +endif + +extra_include_dirs = ['..'] +xmlxx_library = library(xmlxx_libname, + source_cc_files, + extra_xmlxx_objects, + version: xmlxx_libversion, + darwin_versions: macos_darwin_versions, + implicit_include_directories: false, + include_directories: extra_include_dirs, + cpp_args: xmlxx_cpp_args, + dependencies: xmlxx_build_dep, + install: true, +) + +# Generate .pc files, used by pkg-config. +pkg_config = import('pkgconfig') +pc_common_variables = [ + 'doxytagfile=${docdir}/reference/' + xmlxx_pcname + '.tag', + 'htmlrefdir=${docdir}/reference/html', + 'htmlrefpub=https://libxmlplusplus.github.io/libxmlplusplus/reference/html', +] +pc_variables = [ + 'exec_prefix=${prefix}', + 'datarootdir=${datadir}', + 'docdir=${datadir}/doc/' + xmlxx_pcname, +] + pc_common_variables +pc_uninstalled_variables = [ + 'docdir=${prefix}/docs', +] + pc_common_variables + +pkg_config.generate(xmlxx_library, + filebase: xmlxx_pcname, + variables: pc_variables, + uninstalled_variables: pc_uninstalled_variables, + name: meson.project_name(), + description: 'C++ wrapper for libxml2', + url: 'https://libxmlplusplus.github.io/libxmlplusplus/', + requires: xmlxx_pc_requires, + libraries: libxml2_lib_pkgconfig, + subdirs: [xmlxx_pcname], + extra_cflags: ['-I${libdir}/' + xmlxx_pcname + '/include'], +) + +# This is used when building example programs and test programs. +# It's also a part of xmlxx_dep, when libxml++ is a subproject. +xmlxx_own_dep = declare_dependency( + link_with: xmlxx_library, + include_directories: extra_include_dirs, + dependencies: xmlxx_all_deps +) diff --git a/libxml++/nodes/cdatanode.cc b/libxml++/nodes/cdatanode.cc index 0955732f..12a0e846 100644 --- a/libxml++/nodes/cdatanode.cc +++ b/libxml++/nodes/cdatanode.cc @@ -5,13 +5,12 @@ */ #include -#include #include namespace xmlpp { - + CdataNode::CdataNode(xmlNode* node) : ContentNode(node) {} diff --git a/libxml++/nodes/cdatanode.h b/libxml++/nodes/cdatanode.h index cf132694..9160d1aa 100644 --- a/libxml++/nodes/cdatanode.h +++ b/libxml++/nodes/cdatanode.h @@ -15,7 +15,7 @@ namespace xmlpp /** CData node. This will be instantiated by the parser. * */ -class CdataNode : public ContentNode +class LIBXMLPP_API CdataNode : public ContentNode { public: explicit CdataNode(_xmlNode* node); diff --git a/libxml++/nodes/commentnode.cc b/libxml++/nodes/commentnode.cc index 046205c4..aa066cf7 100644 --- a/libxml++/nodes/commentnode.cc +++ b/libxml++/nodes/commentnode.cc @@ -5,7 +5,6 @@ */ #include -#include #include diff --git a/libxml++/nodes/commentnode.h b/libxml++/nodes/commentnode.h index 1dbcbe1c..a1172905 100644 --- a/libxml++/nodes/commentnode.h +++ b/libxml++/nodes/commentnode.h @@ -12,9 +12,9 @@ namespace xmlpp { -/** Comment Node. This will be instantiated by the parser. +/** Comment node. This will be instantiated by the parser. */ -class CommentNode : public ContentNode +class LIBXMLPP_API CommentNode : public ContentNode { public: explicit CommentNode(_xmlNode* node); diff --git a/libxml++/nodes/contentnode.cc b/libxml++/nodes/contentnode.cc index 7153c3c0..a7a42535 100644 --- a/libxml++/nodes/contentnode.cc +++ b/libxml++/nodes/contentnode.cc @@ -11,7 +11,7 @@ namespace xmlpp { - + ContentNode::ContentNode(xmlNode* node) : Node(node) {} @@ -19,7 +19,8 @@ ContentNode::ContentNode(xmlNode* node) ContentNode::~ContentNode() {} -Glib::ustring ContentNode::get_content() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring ContentNode::get_content() const { if(cobj()->type == XML_ELEMENT_NODE) { @@ -28,13 +29,25 @@ Glib::ustring ContentNode::get_content() const return cobj()->content ? (char*)cobj()->content : ""; } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional ContentNode::get_content2() const +{ + if (cobj()->type == XML_ELEMENT_NODE) + throw internal_error("this node type doesn't have content"); + + if (!cobj()->content) + return {}; + + return (char*)cobj()->content; +} -void ContentNode::set_content(const Glib::ustring& content) +void ContentNode::set_content(const ustring& content) { if(cobj()->type == XML_ELEMENT_NODE) { throw internal_error("can't set content for this node type"); - } + } xmlNodeSetContent(cobj(), (xmlChar*)content.c_str()); } diff --git a/libxml++/nodes/contentnode.h b/libxml++/nodes/contentnode.h index 592f57f0..b074ac8d 100644 --- a/libxml++/nodes/contentnode.h +++ b/libxml++/nodes/contentnode.h @@ -12,25 +12,36 @@ namespace xmlpp { -/** Content Node. This will be instantiated by the parser. +/** Content node. This will be instantiated by the parser. */ -class ContentNode : public Node +class LIBXMLPP_API ContentNode : public Node { public: explicit ContentNode(_xmlNode* node); ~ContentNode() override; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the text of this content node. * @returns The text. Note that the 5 predefined entities (&, ", <, >, ') * are always resolved, so this content will show their human-readable equivalents. + * @deprecated 5.6: Use get_content2() instead. */ - Glib::ustring get_content() const; + ustring get_content() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the text of this content node. + * @returns The text, or no value if this node has no text. Note that the 5 + * predefined entities (&, ", <, >, ') are always resolved, + * so this content will show their human-readable equivalents. + * @newin{5,6} + */ + std::optional get_content2() const; /** Set the text of this content node * @param content The text. This must be unescaped, meaning that the predefined entities will be created for you where necessary. * See get_content(). */ - void set_content(const Glib::ustring& content); + void set_content(const ustring& content); /// @returns Whether this node contains only white space, or is empty. bool is_white_space() const; diff --git a/libxml++/nodes/element.cc b/libxml++/nodes/element.cc index a2a4f550..64abd3f2 100644 --- a/libxml++/nodes/element.cc +++ b/libxml++/nodes/element.cc @@ -6,10 +6,26 @@ #include #include -#include #include + +namespace // anonymous +{ +// Common part of all add_child_element*() methods. +xmlpp::Element* add_child_element_common(const xmlpp::ustring& name, xmlNode* child, xmlNode* node) +{ + if (!node) + { + xmlFreeNode(child); + throw xmlpp::internal_error("Could not add child element node " + name); + } + xmlpp::Node::create_wrapper(node); + return static_cast(node->_private); +} + +} // anonymous namespace + namespace xmlpp { @@ -23,31 +39,36 @@ Element::~Element() Element::AttributeList Element::get_attributes() { AttributeList attributes; - for(auto attr = cobj()->properties; attr; attr = attr->next) + for (auto attr = cobj()->properties; attr; attr = attr->next) { Node::create_wrapper(reinterpret_cast(attr)); attributes.push_back(reinterpret_cast(attr->_private)); } - return attributes; } -const Element::AttributeList Element::get_attributes() const +Element::const_AttributeList Element::get_attributes() const { - return const_cast(this)->get_attributes(); + const_AttributeList attributes; + for (auto attr = cobj()->properties; attr; attr = attr->next) + { + Node::create_wrapper(reinterpret_cast(attr)); + attributes.push_back(reinterpret_cast(attr->_private)); + } + return attributes; } -Attribute* Element::get_attribute(const Glib::ustring& name, - const Glib::ustring& ns_prefix) const +Attribute* Element::get_attribute(const ustring& name, + const ustring& ns_prefix) { // An empty ns_prefix means "use no namespace". // The default namespace never applies to an attribute. - Glib::ustring ns_uri; + ustring ns_uri; if (!ns_prefix.empty()) { ns_uri = get_namespace_uri_for_prefix(ns_prefix); if (ns_uri.empty()) - return 0; // No such prefix. + return nullptr; // No such prefix. } // The return value of xmlHasNsProp() may be either an xmlAttr*, pointing to an @@ -55,24 +76,41 @@ Attribute* Element::get_attribute(const Glib::ustring& name, // cast to an xmlAttr*, pointing to the declaration of an attribute with a // default value (XML_ATTRIBUTE_DECL). auto attr = xmlHasNsProp(const_cast(cobj()), (const xmlChar*)name.c_str(), - ns_uri.empty() ? 0 : (const xmlChar*)ns_uri.c_str()); + ns_uri.empty() ? nullptr : (const xmlChar*)ns_uri.c_str()); if (attr) { Node::create_wrapper(reinterpret_cast(attr)); return reinterpret_cast(attr->_private); } - return 0; + return nullptr; +} + +const Attribute* Element::get_attribute(const ustring& name, + const ustring& ns_prefix) const +{ + return const_cast(this)->get_attribute(name, ns_prefix); +} + +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Element::get_attribute_value(const ustring& name, const ustring& ns_prefix) const +{ + const auto attr = get_attribute(name, ns_prefix); + return attr ? attr->get_value() : ustring(); } +#endif // LIBXMLXX_DISABLE_DEPRECATED -Glib::ustring Element::get_attribute_value(const Glib::ustring& name, const Glib::ustring& ns_prefix) const +std::optional Element::get_attribute_value2( + const ustring& name, const ustring& ns_prefix) const { const auto attr = get_attribute(name, ns_prefix); - return attr ? attr->get_value() : Glib::ustring(); + if (!attr) + return {}; + return attr->get_value2(); } -Attribute* Element::set_attribute(const Glib::ustring& name, const Glib::ustring& value, - const Glib::ustring& ns_prefix) +Attribute* Element::set_attribute(const ustring& name, const ustring& value, + const ustring& ns_prefix) { xmlAttr* attr = nullptr; @@ -102,58 +140,187 @@ Attribute* Element::set_attribute(const Glib::ustring& name, const Glib::ustring return reinterpret_cast(attr->_private); } else - return 0; + return nullptr; } -void Element::remove_attribute(const Glib::ustring& name, const Glib::ustring& ns_prefix) +void Element::remove_attribute(const ustring& name, const ustring& ns_prefix) { + // xmlHasProp() seaches for an attribute with a specified name in any namespace. + // Not useful here. + // xmlHasNsProp() seaches both for an attribute node in the element node + // and for an attribute declaration in the DTD. + // xmlUnsetProp() or xmlUnsetNsProp() won't delete an attribute declaration. + auto attr = xmlHasNsProp(cobj(), (const xmlChar*)name.c_str(), + ns_prefix.empty() ? nullptr : (const xmlChar*)ns_prefix.c_str()); + if (!attr || attr->type == XML_ATTRIBUTE_DECL) + return; + if (ns_prefix.empty()) + { + // *this has an attribute with the specified name and no namespace. + // xmlUnsetProp() will delete the existing attribute. + // Delete the C++ wrapper before the call to xmlUnsetProp(). + Node::free_wrappers(reinterpret_cast(attr)); xmlUnsetProp(cobj(), (const xmlChar*)name.c_str()); + } else { auto ns = xmlSearchNs(cobj()->doc, cobj(), (const xmlChar*)ns_prefix.c_str()); if (ns) + { + // *this has an attribute with the specified name and namespace. + // xmlUnsetNsProp() will delete the existing attribute. + // Delete the C++ wrapper before the call to xmlUnsetNsProp(). + Node::free_wrappers(reinterpret_cast(attr)); xmlUnsetNsProp(cobj(), ns, (const xmlChar*)name.c_str()); + } } } -const TextNode* Element::get_child_text() const +Element* Element::add_child_element(const ustring& name, + const ustring& ns_prefix) { - // FIXME: return only the first content node - for(auto child = cobj()->children; child; child = child->next) - if(child->type == XML_TEXT_NODE) - { - Node::create_wrapper(child); - return static_cast(child->_private); - } + auto child = create_new_child_element_node(name, ns_prefix); + auto node = xmlAddChild(cobj(), child); + return add_child_element_common(name, child, node); +} - return 0; +Element* Element::add_child_element(xmlpp::Node* previous_sibling, + const ustring& name, const ustring& ns_prefix) +{ + if (!previous_sibling) + return nullptr; + + auto child = create_new_child_element_node(name, ns_prefix); + auto node = xmlAddNextSibling(previous_sibling->cobj(), child); + return add_child_element_common(name, child, node); } -TextNode* Element::get_child_text() +Element* Element::add_child_element_before(xmlpp::Node* next_sibling, + const ustring& name, const ustring& ns_prefix) { - // TODO: This only returns the first content node. - // What should we do instead? Update the documentation if we change this. murrayc. - for(auto child = cobj()->children; child; child = child->next) - if(child->type == XML_TEXT_NODE) + if (!next_sibling) + return nullptr; + + auto child = create_new_child_element_node(name, ns_prefix); + auto node = xmlAddPrevSibling(next_sibling->cobj(), child); + return add_child_element_common(name, child, node); +} + +Element* Element::add_child_element_with_new_ns(const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix) +{ + auto child = create_new_child_element_node_with_new_ns(name, ns_uri, ns_prefix); + auto node = xmlAddChild(cobj(), child); + return add_child_element_common(name, child, node); +} + +Element* Element::add_child_element_with_new_ns(xmlpp::Node* previous_sibling, + const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix) +{ + if (!previous_sibling) + return nullptr; + + auto child = create_new_child_element_node_with_new_ns(name, ns_uri, ns_prefix); + auto node = xmlAddNextSibling(previous_sibling->cobj(), child); + return add_child_element_common(name, child, node); +} + +Element* Element::add_child_element_before_with_new_ns(xmlpp::Node* next_sibling, + const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix) +{ + if (!next_sibling) + return nullptr; + + auto child = create_new_child_element_node_with_new_ns(name, ns_uri, ns_prefix); + auto node = xmlAddPrevSibling(next_sibling->cobj(), child); + return add_child_element_common(name, child, node); +} + +_xmlNode* Element::create_new_child_element_node(const ustring& name, + const ustring& ns_prefix) +{ + xmlNs* ns = nullptr; + + if (cobj()->type != XML_ELEMENT_NODE) + throw internal_error("You can only add child nodes to element nodes"); + + if (ns_prefix.empty()) + { + //Retrieve default namespace if it exists + ns = xmlSearchNs(cobj()->doc, cobj(), nullptr); + } + else + { + //Use the existing namespace if one exists: + ns = xmlSearchNs(cobj()->doc, cobj(), (const xmlChar*)ns_prefix.c_str()); + if (!ns) + throw exception("The namespace prefix (" + ns_prefix + ") has not been declared."); + } + + return xmlNewNode(ns, (const xmlChar*)name.c_str()); +} + +_xmlNode* Element::create_new_child_element_node_with_new_ns(const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix) +{ + if (cobj()->type != XML_ELEMENT_NODE) + throw internal_error("You can only add child nodes to element nodes."); + + auto child = xmlNewNode(nullptr, (const xmlChar*)name.c_str()); + if (!child) + throw internal_error("Could not create new element node."); + + auto ns = xmlNewNs(child, (const xmlChar*)(ns_uri.empty() ? nullptr : ns_uri.c_str()), + (const xmlChar*)(ns_prefix.empty() ? nullptr : ns_prefix.c_str()) ); + // xmlNewNs() does not create a namespace node for the predefined xml prefix. + // It's usually defined in the document and not in any specific node. + if (!ns && ns_prefix == "xml") + { + ns = xmlSearchNs(cobj()->doc, cobj(), (const xmlChar*)ns_prefix.c_str()); + if (ns && (ns_uri != (ns->href ? (const char*)ns->href : ""))) + ns = nullptr; + } + if (!ns) + { + xmlFreeNode(child); + throw internal_error("Could not create new namespace node."); + } + + xmlSetNs(child, ns); + + return child; +} + +TextNode* Element::get_first_child_text() +{ + for (auto child = cobj()->children; child; child = child->next) + if (child->type == XML_TEXT_NODE) { Node::create_wrapper(child); return static_cast(child->_private); } - return 0; + return nullptr; +} + +const TextNode* Element::get_first_child_text() const +{ + return const_cast(this)->get_first_child_text(); } -void Element::set_child_text(const Glib::ustring& content) +void Element::set_first_child_text(const ustring& content) { - auto node = get_child_text(); + auto node = get_first_child_text(); if(node) node->set_content(content); else add_child_text(content); } -TextNode* Element::add_child_text(const Glib::ustring& content) +TextNode* Element::add_child_text(const ustring& content) { if(cobj()->type == XML_ELEMENT_NODE) { @@ -169,13 +336,13 @@ TextNode* Element::add_child_text(const Glib::ustring& content) Node::create_wrapper(node); return static_cast(node->_private); } - return 0; + return nullptr; } -TextNode* Element::add_child_text(xmlpp::Node* previous_sibling, const Glib::ustring& content) +TextNode* Element::add_child_text(xmlpp::Node* previous_sibling, const ustring& content) { if(!previous_sibling) - return 0; + return nullptr; if(cobj()->type == XML_ELEMENT_NODE) { @@ -191,13 +358,13 @@ TextNode* Element::add_child_text(xmlpp::Node* previous_sibling, const Glib::ust Node::create_wrapper(node); return static_cast(node->_private); } - return 0; + return nullptr; } -TextNode* Element::add_child_text_before(xmlpp::Node* next_sibling, const Glib::ustring& content) +TextNode* Element::add_child_text_before(xmlpp::Node* next_sibling, const ustring& content) { if(!next_sibling) - return 0; + return nullptr; if(cobj()->type == XML_ELEMENT_NODE) { @@ -213,24 +380,24 @@ TextNode* Element::add_child_text_before(xmlpp::Node* next_sibling, const Glib:: Node::create_wrapper(node); return static_cast(node->_private); } - return 0; + return nullptr; } bool Element::has_child_text() const { - return get_child_text() != nullptr; + return get_first_child_text() != nullptr; } -void Element::set_namespace_declaration(const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix) +void Element::set_namespace_declaration(const ustring& ns_uri, const ustring& ns_prefix) { //Create a new namespace declaration for this element: - auto ns = xmlNewNs(cobj(), (const xmlChar*)(ns_uri.empty() ? 0 : ns_uri.c_str()), - (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) ); + auto ns = xmlNewNs(cobj(), (const xmlChar*)(ns_uri.empty() ? nullptr : ns_uri.c_str()), + (const xmlChar*)(ns_prefix.empty() ? nullptr : ns_prefix.c_str()) ); if (!ns) { // Not an error, if we try to assign the same uri to the prefix once again. ns = xmlSearchNs(cobj()->doc, cobj(), - (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str())); + (const xmlChar*)(ns_prefix.empty() ? nullptr : ns_prefix.c_str())); const char* const previous_href = (ns && ns->href) ? (const char*)ns->href : ""; if (!ns || ns_uri != previous_href) throw exception("Could not add namespace declaration with URI=" + ns_uri + @@ -245,27 +412,23 @@ void Element::set_namespace_declaration(const Glib::ustring& ns_uri, const Glib: //We ignore the returned xmlNs*. It's owned by the XML_ELEMENT_NODE. } -Glib::ustring Element::get_namespace_uri_for_prefix(const Glib::ustring& ns_prefix) const +ustring Element::get_namespace_uri_for_prefix(const ustring& ns_prefix) const { - Glib::ustring result; - + ustring result; + //Find the namespace: const auto ns = xmlSearchNs( cobj()->doc, const_cast(cobj()), (xmlChar*)ns_prefix.c_str() ); - if(ns) - { - //Get the namespace URI associated with this prefix: - if(ns && ns->href) - result = (const char*)ns->href; - } - + //Get the namespace URI associated with this prefix: + if (ns && ns->href) + result = (const char*)ns->href; + return result; } - -CommentNode* Element::add_child_comment(const Glib::ustring& content) +CommentNode* Element::add_child_comment(const ustring& content) { auto child = xmlNewComment((const xmlChar*)content.c_str()); - + // Use the result, because child can be freed when merging text nodes: auto node = xmlAddChild(cobj(), child); if (!node) @@ -277,10 +440,9 @@ CommentNode* Element::add_child_comment(const Glib::ustring& content) return static_cast(node->_private); } - -CdataNode* Element::add_child_cdata(const Glib::ustring& content) +CdataNode* Element::add_child_cdata(const ustring& content) { - auto child = xmlNewCDataBlock(cobj()->doc, (const xmlChar*)content.c_str(), content.bytes()); + auto child = xmlNewCDataBlock(cobj()->doc, (const xmlChar*)content.c_str(), content.size()); auto node = xmlAddChild(cobj(), child); if (!node) { @@ -291,7 +453,7 @@ CdataNode* Element::add_child_cdata(const Glib::ustring& content) return static_cast(node->_private); } -EntityReference* Element::add_child_entity_reference(const Glib::ustring& name) +EntityReference* Element::add_child_entity_reference(const ustring& name) { const auto extended_name = name + " "; // This is at least two chars long. int ichar = 0; @@ -316,7 +478,7 @@ EntityReference* Element::add_child_entity_reference(const Glib::ustring& name) } ProcessingInstructionNode* Element::add_child_processing_instruction( - const Glib::ustring& name, const Glib::ustring& content) + const ustring& name, const ustring& content) { auto child = xmlNewDocPI(cobj()->doc, (const xmlChar*)name.c_str(), (const xmlChar*)content.c_str()); auto node = xmlAddChild(cobj(), child); diff --git a/libxml++/nodes/element.h b/libxml++/nodes/element.h index 1cad9bd7..8252ab31 100644 --- a/libxml++/nodes/element.h +++ b/libxml++/nodes/element.h @@ -18,15 +18,17 @@ namespace xmlpp { -/** Element nodes have attributes as well as child nodes. This will be instantiated by the parser. +/** %Element nodes have attributes as well as child nodes. + * This will be instantiated by the parser. */ -class Element : public Node +class LIBXMLPP_API Element : public Node { public: explicit Element(_xmlNode* node); ~Element() override; - typedef std::list AttributeList; + using AttributeList = std::list; + using const_AttributeList = std::list; /** Add a namespace declaration to this node which will apply to this node and all children. * @@ -43,7 +45,7 @@ class Element : public Node * @throws xmlpp::exception If a new namespace node cannot be created, * e.g. because a namespace with the same prefix but another URI already exists. */ - void set_namespace_declaration(const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring()); + void set_namespace_declaration(const ustring& ns_uri, const ustring& ns_prefix = ustring()); /** Obtain the list of explicitly set attributes for this element. * @returns The list of explicitly set attributes. @@ -53,31 +55,51 @@ class Element : public Node /** Obtain the list of explicitly set attributes for this element. * @returns The list of explicitly set attributes. */ - const AttributeList get_attributes() const; + const_AttributeList get_attributes() const; - //TODO: There should be a const and non-const version. - //See the patch at https://bugzilla.gnome.org/show_bug.cgi?id=632524 /** Get the attribute with this name, and optionally with this namespace. * @param name The name of the attribute that will be retrieved. * @param ns_prefix Namespace prefix. - * @return The attribute, or 0 if no suitable Attribute was found. + * @return The attribute, or nullptr if no suitable Attribute was found. * Is either an AttributeNode*, pointing to an explicitly set * attribute, or an AttributeDeclaration*, pointing to the declaration * of an attribute with a default value. */ - Attribute* get_attribute(const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()) const; + Attribute* get_attribute(const ustring& name, + const ustring& ns_prefix = ustring()); + /** Get the attribute with this name, and optionally with this namespace. + * @param name The name of the attribute that will be retrieved. + * @param ns_prefix Namespace prefix. + * @return The attribute, or nullptr if no suitable Attribute was found. + * Is either an AttributeNode*, pointing to an explicitly set + * attribute, or an AttributeDeclaration*, pointing to the declaration + * of an attribute with a default value. + */ + const Attribute* get_attribute(const ustring& name, + const ustring& ns_prefix = ustring()) const; + +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the value of the attribute with this name, and optionally with this namespace. * For finer control, you might use get_attribute() and use the methods of the Attribute class. * @param name The name of the attribute whose value will be retrieved. * @param ns_prefix Namespace prefix. * @return The text value of the attribute, or an empty string if no such attribute was found. - * - * @newin{2,20} + * @deprecated 5.6: Use get_attribute_value2() instead. */ - Glib::ustring get_attribute_value(const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()) const; + ustring get_attribute_value(const ustring& name, + const ustring& ns_prefix = ustring()) const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the value of the attribute with this name, and optionally with this namespace. + * For finer control, you might use get_attribute() and use the methods of the Attribute class. + * @param name The name of the attribute whose value will be retrieved. + * @param ns_prefix Namespace prefix. + * @return The text value of the attribute, or no value if no such attribute was found. + * @newin{5,6} + */ + std::optional get_attribute_value2(const ustring& name, + const ustring& ns_prefix = {}) const; /** Set the value of the attribute with this name, and optionally with this namespace. * A matching attribute will be added if no matching attribute already exists. @@ -85,38 +107,137 @@ class Element : public Node * @param name The name of the attribute whose value will change. * @param value The new value for the attribute * @param ns_prefix Namespace prefix. If the prefix has not been declared then this method will throw an exception. - * @return The attribute that was changed, or 0 is no suitable Attribute was found. + * @return The attribute that was changed, or nullptr is no suitable Attribute was found. * @throws xmlpp::exception */ - Attribute* set_attribute(const Glib::ustring& name, const Glib::ustring& value, - const Glib::ustring& ns_prefix = Glib::ustring()); + Attribute* set_attribute(const ustring& name, const ustring& value, + const ustring& ns_prefix = ustring()); /** Remove the attribute with this name, and optionally with this namespace. * @param name The name of the attribute to be removed * @param ns_prefix Namespace prefix. If specified, the attribute will be removed only if the attribute has this namespace. */ - void remove_attribute(const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()); + void remove_attribute(const ustring& name, + const ustring& ns_prefix = ustring()); + /** Add a child element to this node. + * + * @newin{3,0} Replaces Node::add_child() + * + * @param name The new node name + * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. + * @returns The newly-created element + * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node cannot be created. + */ + Element* add_child_element(const ustring& name, + const ustring& ns_prefix = ustring()); + + /** Add a child element to this node after the specified existing child node. + * + * @newin{3,0} Replaces Node::add_child() + * + * @param previous_sibling An existing child node. + * @param name The new node name + * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. + * @returns The newly-created element + * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node cannot be created. + */ + Element* add_child_element(xmlpp::Node* previous_sibling, const ustring& name, + const ustring& ns_prefix = ustring()); + + /** Add a child element to this node before the specified existing child node. + * + * @newin{3,0} Replaces Node::add_child_before() + * + * @param next_sibling An existing child node. + * @param name The new node name + * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. + * @returns The newly-created element + * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node cannot be created. + */ + Element* add_child_element_before(xmlpp::Node* next_sibling, const ustring& name, + const ustring& ns_prefix = ustring()); + + /** Add a child element to this node. + * + * @newin{3,0} Replaces Node::add_child_with_new_ns() + * + * @param name The new node name. + * @param ns_uri The namespace to associate with the prefix, + * or to use as the default namespace if no prefix is specified. + * @param ns_prefix The prefix of the node's namespace. If no prefix is specified + * then the namespace URI will be the default namespace. + * @returns The newly-created element. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node or the namespace node cannot be created. + */ + Element* add_child_element_with_new_ns(const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix = ustring()); + + /** Add a child element to this node after the specified existing child node. + * + * @newin{3,0} Replaces Node::add_child_with_new_ns() + * + * @param previous_sibling An existing child node. + * @param name The new node name. + * @param ns_uri The namespace to associate with the prefix, + * or to use as the default namespace if no prefix is specified. + * @param ns_prefix The prefix of the node's namespace. If no prefix is specified + * then the namespace URI will be the default namespace. + * @returns The newly-created element. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node or the namespace node cannot be created. + */ + Element* add_child_element_with_new_ns(xmlpp::Node* previous_sibling, const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix = ustring()); + + /** Add a child element to this node before the specified existing child node. + * + * @newin{3,0} Replaces Node::add_child_before_with_new_ns() + * + * @param next_sibling An existing child node. + * @param name The new node name. + * @param ns_uri The namespace to associate with the prefix, + * or to use as the default namespace if no prefix is specified. + * @param ns_prefix The prefix of the node's namespace. If no prefix is specified + * then the namespace URI will be the default namespace. + * @returns The newly-created element. + * @throws xmlpp::internal_error If this node is not an element node, + * or the child node or the namespace node cannot be created. + */ + Element* add_child_element_before_with_new_ns(xmlpp::Node* next_sibling, const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix = ustring()); /** Get the first child text content node. - * This is a convenience method, meant as an alternative to iterating over all the child nodes to find the first suitable node then and getting the text directly. + * This is a convenience method, meant as an alternative to iterating over all the + * child nodes to find the first suitable node and then getting the text directly. * @returns The first text node, if any. + * + * @newin{3,0} Replaces get_child_text(). */ - TextNode* get_child_text(); + TextNode* get_first_child_text(); /** Get the first child text content node. - * This is a convenience method, meant as an alternative to iterating over all the child nodes to find the first suitable node then and getting the text directly. + * This is a convenience method, meant as an alternative to iterating over all the + * child nodes to find the first suitable node and then getting the text directly. * @returns The first text node, if any. + * + * @newin{3,0} Replaces get_child_text(). */ - const TextNode* get_child_text() const; + const TextNode* get_first_child_text() const; /** Append a new text node. * @param content The text. This should be unescaped - see ContentNode::set_content(). * @returns The new text node. * @throws xmlpp::internal_error */ - TextNode* add_child_text(const Glib::ustring& content = Glib::ustring()); + TextNode* add_child_text(const ustring& content = ustring()); /** Add a new text node after the specified existing child node. * @@ -127,7 +248,7 @@ class Element : public Node * @returns The new text node. * @throws xmlpp::internal_error */ - TextNode* add_child_text(xmlpp::Node* previous_sibling, const Glib::ustring& content = Glib::ustring()); + TextNode* add_child_text(xmlpp::Node* previous_sibling, const ustring& content = ustring()); /** Add a new text node before the specified existing child node. * @@ -138,14 +259,17 @@ class Element : public Node * @returns The new text node. * @throws xmlpp::internal_error */ - TextNode* add_child_text_before(xmlpp::Node* next_sibling, const Glib::ustring& content = Glib::ustring()); + TextNode* add_child_text_before(xmlpp::Node* next_sibling, const ustring& content = ustring()); /** Set the text of the first text node, adding one if necessary. - * This is a convenience method, meant as an alternative to iterating over all the child nodes to find the first suitable node then and setting the text directly. + * This is a convenience method, meant as an alternative to iterating over all the + * child nodes to find the first suitable node and then setting the text directly. * @param content The text. This should be unescaped - see ContentNode::set_content(). * @throws xmlpp::internal_error + * + * @newin{3,0} Replaces set_child_text(). */ - void set_child_text(const Glib::ustring& content); + void set_first_child_text(const ustring& content); /** Discover whether one of the child nodes is a text node. * This is a convenience method, meant as an alternative to iterating over all the child nodes and examining them directly. @@ -158,14 +282,14 @@ class Element : public Node * @returns The new comment node. * @throws xmlpp::internal_error */ - CommentNode* add_child_comment(const Glib::ustring& content); + CommentNode* add_child_comment(const ustring& content); /** Append a new CDATA node. * @param content The raw text. * @returns The new CDATA node. * @throws xmlpp::internal_error */ - CdataNode* add_child_cdata(const Glib::ustring& content); + CdataNode* add_child_cdata(const ustring& content); /** Append a new entity reference node. * The reference can be either an entity reference ("name" or "&name;") or @@ -181,7 +305,7 @@ class Element : public Node * @returns The new entity reference node. * @throws xmlpp::internal_error */ - EntityReference* add_child_entity_reference(const Glib::ustring& name); + EntityReference* add_child_entity_reference(const ustring& name); /** Append a new processing instruction node. * @@ -193,10 +317,18 @@ class Element : public Node * @throws xmlpp::internal_error */ ProcessingInstructionNode* add_child_processing_instruction( - const Glib::ustring& name, const Glib::ustring& content); + const ustring& name, const ustring& content); + +private: + ustring get_namespace_uri_for_prefix(const ustring& ns_prefix) const; + + ///Create the C instance ready to be added to the parent node. + _xmlNode* create_new_child_element_node(const ustring& name, + const ustring& ns_prefix); -protected: - Glib::ustring get_namespace_uri_for_prefix(const Glib::ustring& ns_prefix) const; + ///Create the C instance ready to be added to the parent node. + _xmlNode* create_new_child_element_node_with_new_ns(const ustring& name, + const ustring& ns_uri, const ustring& ns_prefix); }; } // namespace xmlpp diff --git a/libxml++/nodes/entitydeclaration.cc b/libxml++/nodes/entitydeclaration.cc index 9486cb4d..ba26f409 100644 --- a/libxml++/nodes/entitydeclaration.cc +++ b/libxml++/nodes/entitydeclaration.cc @@ -5,7 +5,7 @@ */ #include -#include +#include namespace xmlpp { @@ -17,24 +17,40 @@ EntityDeclaration::EntityDeclaration(xmlNode* node) EntityDeclaration::~EntityDeclaration() {} -Glib::ustring EntityDeclaration::get_resolved_text() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring EntityDeclaration::get_resolved_text() const { return cobj()->content ? (const char*)cobj()->content : ""; } -Glib::ustring EntityDeclaration::get_original_text() const +ustring EntityDeclaration::get_original_text() const { return cobj()->orig ? (const char*)cobj()->orig : ""; } +#endif // LIBXMLXX_DISABLE_DEPRECATED -xmlEntity* EntityDeclaration::cobj() +std::optional EntityDeclaration::get_resolved_text2() const +{ + if (!cobj()->content) + return {}; + return (const char*)cobj()->content; +} + +std::optional EntityDeclaration::get_original_text2() const +{ + if (!cobj()->orig) + return {}; + return (const char*)cobj()->orig; +} + +xmlEntity* EntityDeclaration::cobj() noexcept { // An XML_ENTITY_DECL is represented by an xmlEntity struct. Reinterpret // the xmlNode pointer stored in the base class as an xmlEntity pointer. return reinterpret_cast(Node::cobj()); } -const xmlEntity* EntityDeclaration::cobj() const +const xmlEntity* EntityDeclaration::cobj() const noexcept { // An XML_ENTITY_DECL is represented by an xmlEntity struct. Reinterpret // the xmlNode pointer stored in the base class as an xmlEntity pointer. diff --git a/libxml++/nodes/entitydeclaration.h b/libxml++/nodes/entitydeclaration.h index 258e24bc..a78f378a 100644 --- a/libxml++/nodes/entitydeclaration.h +++ b/libxml++/nodes/entitydeclaration.h @@ -23,30 +23,49 @@ namespace xmlpp * @newin{2,36} * */ -class EntityDeclaration : public ContentNode +class LIBXMLPP_API EntityDeclaration : public ContentNode { public: explicit EntityDeclaration(_xmlNode* node); ~EntityDeclaration() override; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the text with character references (like "ß") resolved. * If the entity declaration does not contain any reference to another entity, * this is the text that an entity reference would have resolved to, if the XML * document had been parsed with Parser::set_substitute_entities(true). * @returns The text with character references unescaped. + * @deprecated 5.6: Use get_resolved_text2() instead. */ - Glib::ustring get_resolved_text() const; + ustring get_resolved_text() const; /** Get the text as read from the XML or DTD file. * @returns The escaped text. + * @deprecated 5.6: Use get_original_text2() instead. */ - Glib::ustring get_original_text() const; + ustring get_original_text() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the text with character references (like "ß") resolved. + * If the entity declaration does not contain any reference to another entity, + * this is the text that an entity reference would have resolved to, if the XML + * document had been parsed with Parser::set_substitute_entities(true). + * @returns The text with character references unescaped, if any, else no value. + * @newin{5,6} + */ + std::optional get_resolved_text2() const; + + /** Get the text as read from the XML or DTD file. + * @returns The escaped text, if any, else no value. + * @newin{5,6} + */ + std::optional get_original_text2() const; ///Access the underlying libxml implementation. - _xmlEntity* cobj(); + _xmlEntity* cobj() noexcept; ///Access the underlying libxml implementation. - const _xmlEntity* cobj() const; + const _xmlEntity* cobj() const noexcept; }; } // namespace xmlpp diff --git a/libxml++/nodes/entityreference.cc b/libxml++/nodes/entityreference.cc index d8e2f4d9..18e5ccf9 100644 --- a/libxml++/nodes/entityreference.cc +++ b/libxml++/nodes/entityreference.cc @@ -5,13 +5,12 @@ */ #include -#include -#include +#include namespace xmlpp { - + EntityReference::EntityReference(xmlNode* node) : Node(node) {} @@ -19,9 +18,10 @@ EntityReference::EntityReference(xmlNode* node) EntityReference::~EntityReference() {} -Glib::ustring EntityReference::get_resolved_text() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring EntityReference::get_resolved_text() const { - Glib::ustring result; + ustring result; //Get the child xmlEntity node (there should only be 1). auto cChild = cobj()->children; @@ -32,13 +32,13 @@ Glib::ustring EntityReference::get_resolved_text() const if(pch) result = (const char*)pch; } - + return result; } -Glib::ustring EntityReference::get_original_text() const +ustring EntityReference::get_original_text() const { - Glib::ustring result; + ustring result; //Get the child xmlEntity node (there should only be 1). auto cChild = cobj()->children; @@ -49,10 +49,33 @@ Glib::ustring EntityReference::get_original_text() const if(pch) result = (const char*)pch; } - return result; } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional EntityReference::get_resolved_text2() const +{ + // Get the child xmlEntity node (there should only be 1). + auto cChild = cobj()->children; + if (!(cChild && cChild->type == XML_ENTITY_DECL)) + return {}; + auto cEntity = (xmlEntity*)cChild; + if (!cEntity->content) + return {}; + return (const char*)cEntity->content; +} +std::optional EntityReference::get_original_text2() const +{ + // Get the child xmlEntity node (there should only be 1). + auto cChild = cobj()->children; + if (!(cChild && cChild->type == XML_ENTITY_DECL)) + return {}; + auto cEntity = (xmlEntity*)cChild; + if (!cEntity->orig) + return {}; + return (const char*)cEntity->orig; +} } //namespace xmlpp diff --git a/libxml++/nodes/entityreference.h b/libxml++/nodes/entityreference.h index 7d626acc..768cb5d5 100644 --- a/libxml++/nodes/entityreference.h +++ b/libxml++/nodes/entityreference.h @@ -14,25 +14,43 @@ namespace xmlpp /** Entity references refer to previously declared entities. This will be instantiated by the parser. */ -class EntityReference : public Node +class LIBXMLPP_API EntityReference : public Node { public: explicit EntityReference(_xmlNode* node); ~EntityReference() override; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the text with character references (like "ß") resolved. * If the corresponding entity declaration does not contain any reference to * another entity, this is the text that the reference would have resolved to * if the XML document had been parsed with Parser::set_substitute_entities(true). * @returns The text with character references unescaped. + * @deprecated 5.6: Use get_resolved_text2() instead. */ - Glib::ustring get_resolved_text() const; + ustring get_resolved_text() const; /** Get the text as read from the XML or DTD file. * @returns The escaped text. + * @deprecated 5.6: Use get_original_text2() instead. */ - Glib::ustring get_original_text() const; + ustring get_original_text() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + /** Get the text with character references (like "ß") resolved. + * If the corresponding entity declaration does not contain any reference to + * another entity, this is the text that the reference would have resolved to + * if the XML document had been parsed with Parser::set_substitute_entities(true). + * @returns The text with character references unescaped, if any, else no value. + * @newin{5,6} + */ + std::optional get_resolved_text2() const; + + /** Get the text as read from the XML or DTD file. + * @returns The escaped text, if any, else no value. + * @newin{5,6} + */ + std::optional get_original_text2() const; }; } // namespace xmlpp diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc index cd3263e7..cdf03ee4 100644 --- a/libxml++/nodes/node.cc +++ b/libxml++/nodes/node.cc @@ -26,8 +26,157 @@ namespace // anonymous { +xmlpp::Node* _convert_node(xmlNode* node) +{ + xmlpp::Node* res = nullptr; + if (node) + { + xmlpp::Node::create_wrapper(node); + res = static_cast(node->_private); + } + return res; +} + +// Common part of const and non-const get_children() +template +Tlist get_children_common(const xmlpp::ustring& name, xmlNode* child) +{ + Tlist children; + + while (child) + { + if (name.empty() || name == (const char*)child->name) + children.push_back(_convert_node(child)); + + child = child->next; + } + return children; +} + +// A common part of all overloaded xmlpp::Node::find() and eval_xpath() methods. +xmlXPathObject* find_common1(const xmlpp::ustring& xpath, + const xmlpp::Node::PrefixNsMap* namespaces, xmlNode* node) +{ + auto ctxt = xmlXPathNewContext(node->doc); + if (!ctxt) + throw xmlpp::internal_error("Could not create XPath context for " + xpath); + ctxt->node = node; + + if (namespaces) + { + for (const auto& [prefix, ns_uri] : *namespaces) + xmlXPathRegisterNs(ctxt, + reinterpret_cast(prefix.c_str()), + reinterpret_cast(ns_uri.c_str())); + } + + auto result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt); + xmlXPathFreeContext(ctxt); + + if (!result) + throw xmlpp::exception("Invalid XPath: " + xpath); + + return result; +} + +// A common part of all overloaded xmlpp::Node::find() and eval_xpath() methods. +// Tvector == NodeSet or const_NodeSet +// result->type == XPATH_NODESET +template +Tvector find_common2(xmlXPathObject* result, const char* method_name) +{ + auto nodeset = result->nodesetval; + Tvector nodes; + if (nodeset && !xmlXPathNodeSetIsEmpty(nodeset)) + { + const int count = xmlXPathNodeSetGetLength(nodeset); + nodes.reserve(count); + for (int i = 0; i != count; ++i) + { + auto cnode = xmlXPathNodeSetItem(nodeset, i); + if (!cnode) + { + std::cerr << "Node::" << method_name << "(): The xmlNode was null." << std::endl; + continue; + } + + if (cnode->type == XML_NAMESPACE_DECL) + { + // In this case we would cast it to a xmlNs*, + // but this C++ method only returns Nodes. + std::cerr << "Node::" << method_name << "(): Ignoring an xmlNs object." << std::endl; + continue; + } + + //TODO: Check for other cnode->type values? + + nodes.push_back(_convert_node(cnode)); + } + } + else + { + // return empty set + } + + xmlXPathFreeObject(result); + + return nodes; +} + +// Common part of all overloaded xmlpp::Node::find() methods. +template +Tvector find_common(const xmlpp::ustring& xpath, + const xmlpp::Node::PrefixNsMap* namespaces, xmlNode* node) +{ + auto result = find_common1(xpath, namespaces, node); + + if (result->type != XPATH_NODESET) + { + xmlXPathFreeObject(result); + throw xmlpp::internal_error("Only nodeset result types are supported."); + } + return find_common2(result, "find"); +} + +// Common part of all overloaded xmlpp::Node::eval_xpath() methods. +template +std::variant +eval_xpath_common(const xmlpp::ustring& xpath, + const xmlpp::Node::PrefixNsMap* namespaces, xmlNode* node) +{ + auto result = find_common1(xpath, namespaces, node); + + switch (result->type) + { + case XPATH_NODESET: + return find_common2(result, "eval_xpath"); + + case XPATH_BOOLEAN: + { + auto val = static_cast(result->boolval); + xmlXPathFreeObject(result); + return val; + } + case XPATH_NUMBER: + { + double val = result->floatval; + xmlXPathFreeObject(result); + return val; + } + case XPATH_STRING: + { + xmlpp::ustring val = reinterpret_cast(result->stringval); + xmlXPathFreeObject(result); + return val; + } + default: + xmlXPathFreeObject(result); + throw xmlpp::internal_error("Unsupported result type."); + } +} + // Common part of xmlpp::Node::eval_to_[boolean|number|string] -xmlXPathObject* eval_common(const Glib::ustring& xpath, +xmlXPathObject* eval_common(const xmlpp::ustring& xpath, const xmlpp::Node::PrefixNsMap* namespaces, xmlpp::XPathResultType* result_type, xmlNode* node) { @@ -38,14 +187,13 @@ xmlXPathObject* eval_common(const Glib::ustring& xpath, if (namespaces) { - for (xmlpp::Node::PrefixNsMap::const_iterator it = namespaces->begin(); - it != namespaces->end(); ++it) + for (const auto& [prefix, ns_uri] : *namespaces) xmlXPathRegisterNs(ctxt, - reinterpret_cast(it->first.c_str()), - reinterpret_cast(it->second.c_str())); + reinterpret_cast(prefix.c_str()), + reinterpret_cast(ns_uri.c_str())); } - auto xpath_value = xmlXPathEvalExpression( + auto xpath_value = xmlXPathEval( reinterpret_cast(xpath.c_str()), ctxt); xmlXPathFreeContext(ctxt); @@ -53,7 +201,7 @@ xmlXPathObject* eval_common(const Glib::ustring& xpath, if (!xpath_value) { if (result_type) - *result_type = xmlpp::XPATH_RESULT_UNDEFINED; + *result_type = xmlpp::XPathResultType::UNDEFINED; throw xmlpp::exception("Invalid XPath: " + xpath); } @@ -66,14 +214,14 @@ xmlXPathObject* eval_common(const Glib::ustring& xpath, xpath_value->type == XPATH_STRING) *result_type = static_cast(xpath_value->type); else - *result_type = xmlpp::XPATH_RESULT_UNDEFINED; + *result_type = xmlpp::XPathResultType::UNDEFINED; } return xpath_value; } // Common part of all overloaded xmlpp::Node::eval_to_boolean() methods. -bool eval_common_to_boolean(const Glib::ustring& xpath, +bool eval_common_to_boolean(const xmlpp::ustring& xpath, const xmlpp::Node::PrefixNsMap* namespaces, xmlpp::XPathResultType* result_type, xmlNode* node) { @@ -84,7 +232,7 @@ bool eval_common_to_boolean(const Glib::ustring& xpath, } // Common part of all overloaded xmlpp::Node::eval_to_number() methods. -double eval_common_to_number(const Glib::ustring& xpath, +double eval_common_to_number(const xmlpp::ustring& xpath, const xmlpp::Node::PrefixNsMap* namespaces, xmlpp::XPathResultType* result_type, xmlNode* node) { @@ -95,7 +243,7 @@ double eval_common_to_number(const Glib::ustring& xpath, } // Common part of all overloaded xmlpp::Node::eval_to_string() methods. -Glib::ustring eval_common_to_string(const Glib::ustring& xpath, +xmlpp::ustring eval_common_to_string(const xmlpp::ustring& xpath, const xmlpp::Node::PrefixNsMap* namespaces, xmlpp::XPathResultType* result_type, xmlNode* node) { @@ -104,23 +252,11 @@ Glib::ustring eval_common_to_string(const Glib::ustring& xpath, xmlXPathFreeObject(xpath_value); if (result) { - const Glib::ustring uresult(reinterpret_cast(result)); + xmlpp::ustring uresult(reinterpret_cast(result)); xmlFree(result); return uresult; } - return Glib::ustring(); -} - -// Common part of all add_child*() methods. -xmlpp::Element* add_child_common(const Glib::ustring& name, xmlNode* child, xmlNode* node) -{ - if (!node) - { - xmlFreeNode(child); - throw xmlpp::internal_error("Could not add child element node " + name); - } - xmlpp::Node::create_wrapper(node); - return static_cast(node->_private); + return {}; } } // anonymous namespace @@ -132,7 +268,7 @@ Node::Node(xmlNode* node) : impl_(node) { if (!impl_) - throw internal_error("xmlNode pointer cannot be 0"); + throw internal_error("xmlNode pointer cannot be nullptr"); impl_->_private = this; } @@ -148,7 +284,7 @@ const Element* Node::get_parent() const Element* Node::get_parent() { if(!(cobj()->parent && cobj()->parent->type == XML_ELEMENT_NODE)) - return 0; + return nullptr; Node::create_wrapper(cobj()->parent); return static_cast(cobj()->parent->_private); @@ -162,7 +298,7 @@ const Node* Node::get_next_sibling() const Node* Node::get_next_sibling() { if(!cobj()->next) - return 0; + return nullptr; Node::create_wrapper(cobj()->next); return static_cast(cobj()->next->_private); @@ -176,28 +312,17 @@ const Node* Node::get_previous_sibling() const Node* Node::get_previous_sibling() { if(!cobj()->prev) - return 0; + return nullptr; Node::create_wrapper(cobj()->prev); return static_cast(cobj()->prev->_private); } -static Node* _convert_node(xmlNode* node) -{ - Node* res = nullptr; - if(node) - { - Node::create_wrapper(node); - res = static_cast(node->_private); - } - return res; -} - -Node* Node::get_first_child(const Glib::ustring& name) +Node* Node::get_first_child(const ustring& name) { auto child = impl_->children; if(!child) - return 0; + return nullptr; do { @@ -205,167 +330,35 @@ Node* Node::get_first_child(const Glib::ustring& name) return _convert_node(child); } while((child = child->next)); - - return 0; -} -const Node* Node::get_first_child(const Glib::ustring& name) const -{ - return const_cast(this)->get_first_child(name); + return nullptr; } -Node::NodeList Node::get_children(const Glib::ustring& name) +const Node* Node::get_first_child(const ustring& name) const { - auto child = impl_->children; - if(!child) - return NodeList(); - - NodeList children; - do - { - if(name.empty() || name == (const char*)child->name) - children.push_back(_convert_node(child)); - } - while((child = child->next)); - - return children; -} - -const Node::NodeList Node::get_children(const Glib::ustring& name) const -{ - return const_cast(this)->get_children(name); -} - -Element* Node::add_child(const Glib::ustring& name, - const Glib::ustring& ns_prefix) -{ - auto child = create_new_child_node(name, ns_prefix); - auto node = xmlAddChild(impl_, child); - return add_child_common(name, child, node); -} - -Element* Node::add_child(xmlpp::Node* previous_sibling, - const Glib::ustring& name, - const Glib::ustring& ns_prefix) -{ - if (!previous_sibling) - return 0; - - auto child = create_new_child_node(name, ns_prefix); - auto node = xmlAddNextSibling(previous_sibling->cobj(), child); - return add_child_common(name, child, node); -} - -Element* Node::add_child_before(xmlpp::Node* next_sibling, - const Glib::ustring& name, - const Glib::ustring& ns_prefix) -{ - if (!next_sibling) - return 0; - - auto child = create_new_child_node(name, ns_prefix); - auto node = xmlAddPrevSibling(next_sibling->cobj(), child); - return add_child_common(name, child, node); -} - -Element* Node::add_child_with_new_ns(const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix) -{ - auto child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix); - auto node = xmlAddChild(impl_, child); - return add_child_common(name, child, node); -} - -Element* Node::add_child_with_new_ns(xmlpp::Node* previous_sibling, - const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix) -{ - if (!previous_sibling) - return 0; - - auto child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix); - auto node = xmlAddNextSibling(previous_sibling->cobj(), child); - return add_child_common(name, child, node); + return const_cast(this)->get_first_child(name); } -Element* Node::add_child_before_with_new_ns(xmlpp::Node* next_sibling, - const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix) +Node::NodeList Node::get_children(const ustring& name) { - if (!next_sibling) - return 0; - - auto child = create_new_child_node_with_new_ns(name, ns_uri, ns_prefix); - auto node = xmlAddPrevSibling(next_sibling->cobj(), child); - return add_child_common(name, child, node); + return get_children_common(name, impl_->children); } -_xmlNode* Node::create_new_child_node(const Glib::ustring& name, const Glib::ustring& ns_prefix) +Node::const_NodeList Node::get_children(const ustring& name) const { - xmlNs* ns = nullptr; - - if(impl_->type != XML_ELEMENT_NODE) - { - throw internal_error("You can only add child nodes to element nodes"); - } - - if(ns_prefix.empty()) - { - //Retrieve default namespace if it exists - ns = xmlSearchNs(impl_->doc, impl_, 0); - } - else - { - //Use the existing namespace if one exists: - ns = xmlSearchNs(impl_->doc, impl_, (const xmlChar*)ns_prefix.c_str()); - if (!ns) - { - throw exception("The namespace prefix (" + ns_prefix + ") has not been declared."); - } - } - - return xmlNewNode(ns, (const xmlChar*)name.c_str()); + return get_children_common(name, impl_->children); } -_xmlNode* Node::create_new_child_node_with_new_ns(const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix) +//static +void Node::remove_node(Node* node) { - if (impl_->type != XML_ELEMENT_NODE) - throw internal_error("You can only add child nodes to element nodes."); - - auto child = xmlNewNode(0, (const xmlChar*)name.c_str()); - if (!child) - throw internal_error("Could not create new element node."); - - auto ns = xmlNewNs(child, (const xmlChar*)(ns_uri.empty() ? 0 : ns_uri.c_str()), - (const xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) ); - // xmlNewNs() does not create a namespace node for the predefined xml prefix. - // It's usually defined in the document and not in any specific node. - if (!ns && ns_prefix == "xml") - { - ns = xmlSearchNs(impl_->doc, impl_, (const xmlChar*)ns_prefix.c_str()); - if (ns && (ns_uri != (ns->href ? (const char*)ns->href : ""))) - ns = nullptr; - } - if (!ns) - { - xmlFreeNode(child); - throw internal_error("Could not create new namespace node."); - } - - xmlSetNs(child, ns); - - return child; -} - -void Node::remove_child(Node* node) -{ - //TODO: Allow a node to be removed without deleting it, to allow it to be moved? + //TODO: Allow a node to be disconnected from its parent without deleting it, + // to allow it to be moved? //This would require a more complex memory management API. if (!node) return; auto cnode = node->cobj(); - Node::free_wrappers(cnode); //This delete the C++ node (not this) itself. + Node::free_wrappers(cnode); // This deletes the C++ node. xmlUnlinkNode(cnode); xmlFreeNode(cnode); } @@ -373,7 +366,7 @@ void Node::remove_child(Node* node) Node* Node::import_node(const Node* node, bool recursive) { if (!node) - return 0; + return nullptr; //Create the node, by copying: auto imported_node = xmlDocCopyNode(const_cast(node->cobj()), impl_->doc, recursive); @@ -385,7 +378,7 @@ Node* Node::import_node(const Node* node, bool recursive) if (imported_node->type == XML_ATTRIBUTE_NODE && impl_->type == XML_ELEMENT_NODE) { auto old_attr = xmlHasNsProp(impl_, imported_node->name, - imported_node->ns ? imported_node->ns->href : 0); + imported_node->ns ? imported_node->ns->href : nullptr); if (old_attr && old_attr->type != XML_ATTRIBUTE_DECL) { // *this has an attribute with the same name as the imported attribute. @@ -413,12 +406,21 @@ Node* Node::import_node(const Node* node, bool recursive) return static_cast(added_node->_private); } -Glib::ustring Node::get_name() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Node::get_name() const { return impl_->name ? (const char*)impl_->name : ""; } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional Node::get_name2() const +{ + if (!impl_->name) + return {}; + return (const char*)impl_->name; +} -void Node::set_name(const Glib::ustring& name) +void Node::set_name(const ustring& name) { xmlNodeSetName( impl_, (const xmlChar *)name.c_str() ); } @@ -429,147 +431,118 @@ int Node::get_line() const } -xmlNode* Node::cobj() +xmlNode* Node::cobj() noexcept { return impl_; } -const xmlNode* Node::cobj() const +const xmlNode* Node::cobj() const noexcept { return impl_; } -Glib::ustring Node::get_path() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Node::get_path() const { xmlChar* path = xmlGetNodePath(impl_); - Glib::ustring retn = path ? (char*)path : ""; + ustring retn = path ? (char*)path : ""; xmlFree(path); return retn; } +#endif // LIBXMLXX_DISABLE_DEPRECATED -static NodeSet find_impl(xmlXPathContext* ctxt, const Glib::ustring& xpath) +std::optional Node::get_path2() const { - auto result = xmlXPathEval((const xmlChar*)xpath.c_str(), ctxt); - - if(!result) - { - xmlXPathFreeContext(ctxt); - - throw exception("Invalid XPath: " + xpath); - } - - if(result->type != XPATH_NODESET) - { - xmlXPathFreeObject(result); - xmlXPathFreeContext(ctxt); - - throw internal_error("Only nodeset result types are supported."); - } - - auto nodeset = result->nodesetval; - NodeSet nodes; - if( nodeset && !xmlXPathNodeSetIsEmpty(nodeset)) - { - const int count = xmlXPathNodeSetGetLength(nodeset); - nodes.reserve(count); - for (int i = 0; i != count; ++i) - { - auto cnode = xmlXPathNodeSetItem(nodeset, i); - if(!cnode) - { - std::cerr << "Node::find_impl: The xmlNode was null." << std::endl; - continue; - } - - if(cnode->type == XML_NAMESPACE_DECL) - { - //In this case we would cast it to a xmlNs*, - //but this C++ method only returns Nodes. - std::cerr << "Node::find_impl: ignoring an xmlNs object." << std::endl; - continue; - } - - //TODO: Check for other cnode->type values? - - Node::create_wrapper(cnode); - auto cppNode = static_cast(cnode->_private); - nodes.push_back(cppNode); - } - } - else - { - // return empty set - } + xmlChar* path = xmlGetNodePath(impl_); + if (!path) + return {}; + std::optional result = (char*)path; + xmlFree(path); + return result; +} - xmlXPathFreeObject(result); - xmlXPathFreeContext(ctxt); +Node::NodeSet Node::find(const ustring& xpath) +{ + return find_common(xpath, nullptr, impl_); +} - return nodes; +Node::const_NodeSet Node::find(const ustring& xpath) const +{ + return find_common(xpath, nullptr, impl_); } -NodeSet Node::find(const Glib::ustring& xpath) const +Node::NodeSet Node::find(const ustring& xpath, const PrefixNsMap& namespaces) { - auto ctxt = xmlXPathNewContext(impl_->doc); - if (!ctxt) - throw internal_error("Could not create XPath context for " + xpath); - ctxt->node = impl_; - - return find_impl(ctxt, xpath); + return find_common(xpath, &namespaces, impl_); } -NodeSet Node::find(const Glib::ustring& xpath, - const PrefixNsMap& namespaces) const +Node::const_NodeSet Node::find(const ustring& xpath, const PrefixNsMap& namespaces) const { - auto ctxt = xmlXPathNewContext(impl_->doc); - if (!ctxt) - throw internal_error("Could not create XPath context for " + xpath); - ctxt->node = impl_; + return find_common(xpath, &namespaces, impl_); +} - for (PrefixNsMap::const_iterator it=namespaces.begin(); - it != namespaces.end(); it++) - xmlXPathRegisterNs(ctxt, - reinterpret_cast(it->first.c_str()), - reinterpret_cast(it->second.c_str())); +std::variant +Node::eval_xpath(const ustring& xpath, const PrefixNsMap& namespaces) +{ + return eval_xpath_common(xpath, &namespaces, impl_); +} - return find_impl(ctxt, xpath); +std::variant +Node::eval_xpath(const ustring& xpath, const PrefixNsMap& namespaces) const +{ + return eval_xpath_common(xpath, &namespaces, impl_); } -bool Node::eval_to_boolean(const Glib::ustring& xpath, XPathResultType* result_type) const +bool Node::eval_to_boolean(const ustring& xpath, XPathResultType* result_type) const { - return eval_common_to_boolean(xpath, 0, result_type, impl_); + return eval_common_to_boolean(xpath, nullptr, result_type, impl_); } -bool Node::eval_to_boolean(const Glib::ustring& xpath, const PrefixNsMap& namespaces, +bool Node::eval_to_boolean(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type) const { return eval_common_to_boolean(xpath, &namespaces, result_type, impl_); } -double Node::eval_to_number(const Glib::ustring& xpath, XPathResultType* result_type) const +double Node::eval_to_number(const ustring& xpath, XPathResultType* result_type) const { - return eval_common_to_number(xpath, 0, result_type, impl_); + return eval_common_to_number(xpath, nullptr, result_type, impl_); } -double Node::eval_to_number(const Glib::ustring& xpath, const PrefixNsMap& namespaces, +double Node::eval_to_number(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type) const { return eval_common_to_number(xpath, &namespaces, result_type, impl_); } -Glib::ustring Node::eval_to_string(const Glib::ustring& xpath, XPathResultType* result_type) const +ustring Node::eval_to_string(const ustring& xpath, XPathResultType* result_type) const { - return eval_common_to_string(xpath, 0, result_type, impl_); + return eval_common_to_string(xpath, nullptr, result_type, impl_); } -Glib::ustring Node::eval_to_string(const Glib::ustring& xpath, const PrefixNsMap& namespaces, +ustring Node::eval_to_string(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type) const { return eval_common_to_string(xpath, &namespaces, result_type, impl_); } -Glib::ustring Node::get_namespace_prefix() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring Node::get_namespace_prefix() const +{ + return get_namespace_prefix2().value_or(""); +} + +ustring Node::get_namespace_uri() const { - if(impl_->type == XML_DOCUMENT_NODE || impl_->type == XML_ENTITY_DECL) + return get_namespace_uri2().value_or(""); +} +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional Node::get_namespace_prefix2() const +{ + if (impl_->type == XML_DOCUMENT_NODE || + impl_->type == XML_HTML_DOCUMENT_NODE || + impl_->type == XML_ENTITY_DECL) { //impl_ is actually of type xmlDoc or xmlEntity, instead of just xmlNode. //libxml does not always use GObject-style inheritance, so xmlDoc and @@ -577,24 +550,27 @@ Glib::ustring Node::get_namespace_prefix() const //Therefore, a call to impl_->ns would be invalid. //This can be an issue when calling this method on a Node returned by Node::find(). //See the TODO comment on Document, suggesting that Document should derive from Node. - - return Glib::ustring(); + return {}; } - else if (impl_->type == XML_ATTRIBUTE_DECL) + + if (impl_->type == XML_ATTRIBUTE_DECL) { - //impl_ is actually of type xmlAttribute, instead of just xmlNode. - const xmlAttribute* const attr = reinterpret_cast(impl_); - return attr->prefix ? (const char*)attr->prefix : ""; + // impl_ is actually of type xmlAttribute, instead of just xmlNode. + auto attr = reinterpret_cast(impl_); + if (!attr->prefix) + return {}; + return (const char*)attr->prefix; } - else if(impl_->ns && impl_->ns->prefix) - return (char*)impl_->ns->prefix; - else - return Glib::ustring(); + + if (!(impl_->ns && impl_->ns->prefix)) + return {}; + return (const char*)impl_->ns->prefix; } -Glib::ustring Node::get_namespace_uri() const +std::optional Node::get_namespace_uri2() const { if(impl_->type == XML_DOCUMENT_NODE || + impl_->type == XML_HTML_DOCUMENT_NODE || impl_->type == XML_ENTITY_DECL || impl_->type == XML_ATTRIBUTE_DECL) { @@ -604,17 +580,15 @@ Glib::ustring Node::get_namespace_uri() const //Therefore, a call to impl_->ns would be invalid. //This can be an issue when calling this method on a Node returned by Node::find(). //See the TODO comment on Document, suggesting that Document should derived from Node. - - return Glib::ustring(); + return {}; } - if(impl_->ns && impl_->ns->href) - return (char*)impl_->ns->href; - else - return Glib::ustring(); + if (!(impl_->ns && impl_->ns->href)) + return {}; + return (const char*)impl_->ns->href; } -void Node::set_namespace(const Glib::ustring& ns_prefix) +void Node::set_namespace(const ustring& ns_prefix) { if (impl_->type == XML_ATTRIBUTE_DECL) { @@ -622,7 +596,7 @@ void Node::set_namespace(const Glib::ustring& ns_prefix) } //Look for the existing namespace to use: - auto ns = xmlSearchNs( cobj()->doc, cobj(), (xmlChar*)(ns_prefix.empty() ? 0 : ns_prefix.c_str()) ); + auto ns = xmlSearchNs( cobj()->doc, cobj(), (xmlChar*)(ns_prefix.empty() ? nullptr : ns_prefix.c_str()) ); if(ns) { //Use it for this element: @@ -711,6 +685,7 @@ void Node::create_wrapper(xmlNode* node) break; } case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: { // do nothing. For Documents it's the wrapper that is the owner. break; @@ -719,7 +694,7 @@ void Node::create_wrapper(xmlNode* node) { // good default for release versions node->_private = new xmlpp::Node(node); - std::cerr << G_STRFUNC << " Warning: new node of unknown type created: " + std::cerr << "xmlpp::Node::create_wrapper(): Warning: new node of unknown type created: " << node->type << std::endl; break; } @@ -730,7 +705,7 @@ void Node::free_wrappers(xmlNode* node) { if(!node) return; - + //If an entity declaration contains an entity reference, there can be cyclic //references between entity declarations and entity references. (It's not //a tree.) We must avoid an infinite recursion. @@ -759,6 +734,7 @@ void Node::free_wrappers(xmlNode* node) node->_private = nullptr; return; case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: //Do not free now. The Document is usually the one who owns the caller. return; default: @@ -768,13 +744,12 @@ void Node::free_wrappers(xmlNode* node) } //Walk the attributes list. - //Note that some "derived" struct have a different layout, so + //Note that some "derived" struct have a different layout, so //_xmlNode::properties would be a nonsense value, leading to crashes, - //(and shown as valgrind warnings), so we return above, to avoid + //(and shown as valgrind warnings), so we return above, to avoid //checking it here. for(auto attr = node->properties; attr; attr = attr->next) free_wrappers(reinterpret_cast(attr)); } - } //namespace xmlpp diff --git a/libxml++/nodes/node.h b/libxml++/nodes/node.h index 74d0f0e0..c0693600 100644 --- a/libxml++/nodes/node.h +++ b/libxml++/nodes/node.h @@ -9,10 +9,12 @@ #include #include -#include +#include "libxml++/ustring.h" #include #include +#include #include +#include #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { @@ -23,12 +25,7 @@ extern "C" { namespace xmlpp { -class TextNode; -class Element; -class Attribute; - -class Node; -typedef std::vector NodeSet; +class LIBXMLPP_API Element; // xmlpp::XPathResultType is similar to xmlXPathObjectType in libxml2. /** An XPath expression is evaluated to yield a result, which @@ -38,221 +35,168 @@ typedef std::vector NodeSet; * - number * - string */ -enum XPathResultType +enum class XPathResultType { - XPATH_RESULT_UNDEFINED = 0, - XPATH_RESULT_NODESET = 1, - XPATH_RESULT_BOOLEAN = 2, - XPATH_RESULT_NUMBER = 3, - XPATH_RESULT_STRING = 4 + UNDEFINED = 0, + NODESET = 1, + BOOLEAN = 2, + NUMBER = 3, + STRING = 4 }; /** Represents XML Nodes. - * You should never new or delete Nodes. The Parser will create and manage them for you. + * + * You should never new and delete Nodes. The Parser will create and + * manage them for you. Furthermore, Document and Element have methods for + * adding Nodes to a Document. */ -class Node : public NonCopyable +class LIBXMLPP_API Node : public NonCopyable { public: - typedef std::list NodeList; + using NodeList = std::list; + using const_NodeList = std::list; + + using NodeSet = std::vector; + using const_NodeSet = std::vector; - /** @throws xmlpp::internal_error If @a node is 0. + /** @throws xmlpp::internal_error If @a node is nullptr. */ explicit Node(_xmlNode* node); + + /** Destructor. + * Does not destroy the underlying xmlNode. The xmlNode is owned by a xmlDoc + * document. If you want to also destroy the xmlNode, use remove_node(). + */ ~Node() override; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the name of this node. * @returns The node's name. + * @deprecated 5.6: Use get_name2() instead. */ - Glib::ustring get_name() const; + ustring get_name() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the name of this node. + * @returns The node's name, if any, else no value. + * @newin{5,6} + */ + std::optional get_name2() const; /** Set the name of this node. * @param name The new name for the node. */ - void set_name(const Glib::ustring& name); + void set_name(const ustring& name); /** Set the namespace prefix used by the node. * If no such namespace prefix has been declared then this method will throw an exception. * @param ns_prefix The namespace prefix. * @throws xmlpp::exception */ - void set_namespace(const Glib::ustring& ns_prefix); + void set_namespace(const ustring& ns_prefix); +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the namespace prefix of this node. * @returns The node's namespace prefix. Can be an empty string. + * @deprecated 5.6: Use get_namespace_prefix2() instead. */ - Glib::ustring get_namespace_prefix() const; + ustring get_namespace_prefix() const; /** Get the namespace URI of this node. * @returns The node's namespace URI. Can be an empty string. + * @deprecated 5.6: Use get_namespace_uri2() instead. */ - Glib::ustring get_namespace_uri() const; + ustring get_namespace_uri() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the namespace prefix of this node. + * @returns The node's namespace prefix, or no value if the node has no namespace prefix. + * @newin{5,6} + */ + std::optional get_namespace_prefix2() const; + + /** Get the namespace URI of this node. + * @returns The node's namespace URI, or no value if the node has no namespace URI. + * @newin{5,6} + */ + std::optional get_namespace_uri2() const; /** Discover at what line number this node occurs in the XML file. * @returns The line number. */ int get_line() const; - + /** Get the parent element for this node. - * @returns The parent node, or 0 if the node has no parent element. + * @returns The parent node, or nullptr if the node has no parent element. */ - const Element* get_parent() const; + const Element* get_parent() const; /** Get the parent element for this node. - * @returns The parent node, or 0 if the node has no parent element. + * @returns The parent node, or nullptr if the node has no parent element. */ - Element* get_parent(); + Element* get_parent(); /** Get the next sibling for this node. - * @returns The next sibling, or 0 if the node has no next sibling. + * @returns The next sibling, or nullptr if the node has no next sibling. */ - const Node* get_next_sibling() const; + const Node* get_next_sibling() const; /** Get the next sibling for this node. - * @returns The next sibling, or 0 if the node has no next sibling. + * @returns The next sibling, or nullptr if the node has no next sibling. */ - Node* get_next_sibling(); + Node* get_next_sibling(); /** Get the previous sibling for this node . - * @returns The previous sibling, or 0 if the node has no previous sibling. + * @returns The previous sibling, or nullptr if the node has no previous sibling. */ - const Node* get_previous_sibling() const; + const Node* get_previous_sibling() const; /** Get the previous sibling for this node. - * @returns The previous sibling, or 0 if the node has no previous sibling. + * @returns The previous sibling, or nullptr if the node has no previous sibling. */ - Node* get_previous_sibling(); + Node* get_previous_sibling(); /** Get the first child of this node. * You may optionally get the first child node which has a certain name. * @param name The name of the requested child node, or an empty string. - * @returns The first child, or 0 if no child node (with the specified name) exists. + * @returns The first child, or nullptr if no child node (with the specified name) exists. * * @newin{2,36} */ - const Node* get_first_child(const Glib::ustring& name = Glib::ustring()) const; + const Node* get_first_child(const ustring& name = ustring()) const; /** Get the first child of this node. * You may optionally get the first child node which has a certain name. * @param name The name of the requested child node, or an empty string. - * @returns The first child, or 0 if no child node (with the specified name) exists. + * @returns The first child, or nullptr if no child node (with the specified name) exists. * * @newin{2,36} */ - Node* get_first_child(const Glib::ustring& name = Glib::ustring()); + Node* get_first_child(const ustring& name = ustring()); /** Obtain the list of child nodes. You may optionally obtain a list of only the child nodes which have a certain name. * @param name The names of the child nodes to get. If you do not specify a name, then the list will contain all nodes, regardless of their names. * @returns The list of child nodes. */ - NodeList get_children(const Glib::ustring& name = Glib::ustring()); + NodeList get_children(const ustring& name = ustring()); /** Obtain the list of child nodes. You may optionally obtain a list of only the child nodes which have a certain name. * @param name The names of the child nodes to get. If you do not specify a name, then the list will contain all nodes, regardless of their names. * @returns The list of child nodes. */ - const NodeList get_children(const Glib::ustring& name = Glib::ustring()) const; + const_NodeList get_children(const ustring& name = ustring()) const; - /** Add a child element to this node. - * This node must be an element node. - * @param name The new node name - * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. - * @returns The newly-created element - * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node cannot be created. - */ - Element* add_child(const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Add a child element to this node after the specified existing child node. - * This node must be an element node. - * - * @newin{2,24} - * - * @param previous_sibling An existing child node. - * @param name The new node name - * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. - * @returns The newly-created element - * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node cannot be created. - */ - Element* add_child(xmlpp::Node* previous_sibling, const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Add a child element to this node before the specified existing child node. - * This node must be an element node. - * - * @newin{2,24} - * - * @param next_sibling An existing child node. - * @param name The new node name - * @param ns_prefix The namespace prefix. If the prefix has not been declared then this method will throw an exception. - * @returns The newly-created element - * @throws xmlpp::exception If a namespace prefix is specified, but has not been declared. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node cannot be created. - */ - Element* add_child_before(xmlpp::Node* next_sibling, const Glib::ustring& name, - const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Add a child element to this node. - * This node must be an element node. - * - * @newin{2,38} - * - * @param name The new node name. - * @param ns_uri The namespace to associate with the prefix, - * or to use as the default namespace if no prefix is specified. - * @param ns_prefix The prefix of the node's namespace. If no prefix is specified - * then the namespace URI will be the default namespace. - * @returns The newly-created element. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node or the namespace node cannot be created. - */ - Element* add_child_with_new_ns(const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Add a child element to this node after the specified existing child node. - * This node must be an element node. + /** Remove a node and its children. * - * @newin{2,38} + * The node is disconnected from its parent. The underlying libxml xmlNode + * instances are also removed. * - * @param previous_sibling An existing child node. - * @param name The new node name. - * @param ns_uri The namespace to associate with the prefix, - * or to use as the default namespace if no prefix is specified. - * @param ns_prefix The prefix of the node's namespace. If no prefix is specified - * then the namespace URI will be the default namespace. - * @returns The newly-created element. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node or the namespace node cannot be created. - */ - Element* add_child_with_new_ns(xmlpp::Node* previous_sibling, const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Add a child element to this node before the specified existing child node. - * This node must be an element node. + * @newin{3,0} Replaces remove_child() * - * @newin{2,38} - * - * @param next_sibling An existing child node. - * @param name The new node name. - * @param ns_uri The namespace to associate with the prefix, - * or to use as the default namespace if no prefix is specified. - * @param ns_prefix The prefix of the node's namespace. If no prefix is specified - * then the namespace URI will be the default namespace. - * @returns The newly-created element. - * @throws xmlpp::internal_error If this node is not an element node, - * or the child node or the namespace node cannot be created. - */ - Element* add_child_before_with_new_ns(xmlpp::Node* next_sibling, const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix = Glib::ustring()); - - /** Remove the child node. - * @param node The child node to remove. This Node will be deleted and therefore unusable after calling this method. + * @param node The node to remove. This Node and all its descendants will be + * deleted and therefore unusable after calling this method. */ - void remove_child(Node* node); + static void remove_node(Node* node); /** Import node(s) from another document under this node, without affecting the source node. * @@ -269,11 +213,19 @@ class Node : public NonCopyable */ Node* import_node(const Node* node, bool recursive = true); - +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the XPath of this node. * @result The XPath of the node. + * @deprecated 5.6: Use get_path2() instead. */ - Glib::ustring get_path() const; + ustring get_path() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the XPath of this node. + * @result The XPath of the node, or no value in case of error. + * @newin{5,6} + */ + std::optional get_path2() const; /** Find nodes from an XPath expression. * @param xpath The XPath of the nodes. @@ -281,11 +233,19 @@ class Node : public NonCopyable * @throws xmlpp::exception If the XPath expression cannot be evaluated. * @throws xmlpp::internal_error If the result type is not nodeset. */ - NodeSet find(const Glib::ustring& xpath) const; + NodeSet find(const ustring& xpath); + + /** Find nodes from an XPath expression. + * @param xpath The XPath of the nodes. + * @returns The resulting const_NodeSet. + * @throws xmlpp::exception If the XPath expression cannot be evaluated. + * @throws xmlpp::internal_error If the result type is not nodeset. + */ + const_NodeSet find(const ustring& xpath) const; /** A map of namespace prefixes to namespace URIs. */ - typedef std::map PrefixNsMap; + using PrefixNsMap = std::map; /** Find nodes from an XPath expression. * @param xpath The XPath of the nodes. @@ -294,12 +254,47 @@ class Node : public NonCopyable * @throws xmlpp::exception If the XPath expression cannot be evaluated. * @throws xmlpp::internal_error If the result type is not nodeset. */ - NodeSet find(const Glib::ustring& xpath, const PrefixNsMap& namespaces) const; + NodeSet find(const ustring& xpath, const PrefixNsMap& namespaces); + + /** Find nodes from an XPath expression. + * @param xpath The XPath of the nodes. + * @param namespaces A map of namespace prefixes to namespace URIs to be used while finding. + * @returns The resulting const_NodeSet. + * @throws xmlpp::exception If the XPath expression cannot be evaluated. + * @throws xmlpp::internal_error If the result type is not nodeset. + */ + const_NodeSet find(const ustring& xpath, const PrefixNsMap& namespaces) const; + + /** Evaluate an XPath expression. + * @param xpath The XPath expression. + * @param namespaces A map of namespace prefixes to namespace URIs to be used while evaluating. + * @returns The resulting NodeSet (XPathResultType::NODESET), bool (XPathResultType::BOOLEAN), + * double (XPathResultType::NUMBER) or ustring (XPathResultType::STRING). + * @throws xmlpp::exception If the XPath expression cannot be evaluated. + * @throws xmlpp::internal_error If the result type is not nodeset, boolean, number or string. + * + * @newin{5,4} + */ + std::variant + eval_xpath(const ustring& xpath, const PrefixNsMap& namespaces = {}); + + /** Evaluate an XPath expression. + * @param xpath The XPath expression. + * @param namespaces A map of namespace prefixes to namespace URIs to be used while evaluating. + * @returns The resulting const_NodeSet (XPathResultType::NODESET), bool (XPathResultType::BOOLEAN), + * double (XPathResultType::NUMBER) or ustring (XPathResultType::STRING). + * @throws xmlpp::exception If the XPath expression cannot be evaluated. + * @throws xmlpp::internal_error If the result type is not nodeset, boolean, number or string. + * + * @newin{5,4} + */ + std::variant + eval_xpath(const ustring& xpath, const PrefixNsMap& namespaces = {}) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param[out] result_type Result type of the XPath expression before conversion - * to boolean. If 0, the result type is not returned. + * to boolean. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type boolean, * it is converted to boolean. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -307,14 +302,14 @@ class Node : public NonCopyable * * @newin{2,36} */ - bool eval_to_boolean(const Glib::ustring& xpath, XPathResultType* result_type = nullptr) const; + bool eval_to_boolean(const ustring& xpath, XPathResultType* result_type = nullptr) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param namespaces A map of namespace prefixes to namespace URIs to be used while evaluating. * @param[out] result_type Result type of the XPath expression before conversion - * to boolean. If 0, the result type is not returned. + * to boolean. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type boolean, * it is converted to boolean. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -322,13 +317,13 @@ class Node : public NonCopyable * * @newin{2,36} */ - bool eval_to_boolean(const Glib::ustring& xpath, const PrefixNsMap& namespaces, + bool eval_to_boolean(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type = nullptr) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param[out] result_type Result type of the XPath expression before conversion - * to number. If 0, the result type is not returned. + * to number. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type number, * it is converted to number. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -336,13 +331,13 @@ class Node : public NonCopyable * * @newin{2,36} */ - double eval_to_number(const Glib::ustring& xpath, XPathResultType* result_type = nullptr) const; + double eval_to_number(const ustring& xpath, XPathResultType* result_type = nullptr) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param namespaces A map of namespace prefixes to namespace URIs to be used while evaluating. * @param[out] result_type Result type of the XPath expression before conversion - * to number. If 0, the result type is not returned. + * to number. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type number, * it is converted to number. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -350,13 +345,13 @@ class Node : public NonCopyable * * @newin{2,36} */ - double eval_to_number(const Glib::ustring& xpath, const PrefixNsMap& namespaces, + double eval_to_number(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type = nullptr) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param[out] result_type Result type of the XPath expression before conversion - * to string. If 0, the result type is not returned. + * to string. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type string, * it is converted to string. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -364,13 +359,13 @@ class Node : public NonCopyable * * @newin{2,36} */ - Glib::ustring eval_to_string(const Glib::ustring& xpath, XPathResultType* result_type = nullptr) const; + ustring eval_to_string(const ustring& xpath, XPathResultType* result_type = nullptr) const; /** Evaluate an XPath expression. * @param xpath The XPath expression. * @param namespaces A map of namespace prefixes to namespace URIs to be used while evaluating. * @param[out] result_type Result type of the XPath expression before conversion - * to string. If 0, the result type is not returned. + * to string. If nullptr, the result type is not returned. * @returns The value of the XPath expression. If the value is not of type string, * it is converted to string. * @throws xmlpp::exception If the XPath expression cannot be evaluated. @@ -378,14 +373,14 @@ class Node : public NonCopyable * * @newin{2,36} */ - Glib::ustring eval_to_string(const Glib::ustring& xpath, const PrefixNsMap& namespaces, + ustring eval_to_string(const ustring& xpath, const PrefixNsMap& namespaces, XPathResultType* result_type = nullptr) const; ///Access the underlying libxml implementation. - _xmlNode* cobj(); + _xmlNode* cobj() noexcept; ///Access the underlying libxml implementation. - const _xmlNode* cobj() const; + const _xmlNode* cobj() const noexcept; /** Construct the correct C++ instance for a given libxml C struct instance. * @@ -394,23 +389,14 @@ class Node : public NonCopyable * @param node A pointer to an xmlNode or a "derived" struct, such as xmlDoc, xmlAttr, etc. */ static void create_wrapper(_xmlNode* node); - - /** Delete the C++ instance for a given libxml C struct instance, and also + + /** Delete the C++ instance for a given libxml C struct instance, and also * recursively destroy the C++ instances for any children. * * This is only for use by the libxml++ implementation. * @param node A pointer to an xmlNode or a "derived" struct, such as xmlDoc, xmlAttr, etc. */ static void free_wrappers(_xmlNode* node); - -protected: - - ///Create the C instance ready to be added to the parent node. - _xmlNode* create_new_child_node(const Glib::ustring& name, const Glib::ustring& ns_prefix); - - ///Create the C instance ready to be added to the parent node. - _xmlNode* create_new_child_node_with_new_ns(const Glib::ustring& name, - const Glib::ustring& ns_uri, const Glib::ustring& ns_prefix); private: _xmlNode* impl_; diff --git a/libxml++/nodes/processinginstructionnode.cc b/libxml++/nodes/processinginstructionnode.cc index 074fce72..8c033bb6 100644 --- a/libxml++/nodes/processinginstructionnode.cc +++ b/libxml++/nodes/processinginstructionnode.cc @@ -5,13 +5,12 @@ */ #include -#include #include namespace xmlpp { - + ProcessingInstructionNode::ProcessingInstructionNode(xmlNode* node) : ContentNode(node) {} @@ -20,4 +19,3 @@ ProcessingInstructionNode::~ProcessingInstructionNode() {} } //namespace xmlpp - diff --git a/libxml++/nodes/processinginstructionnode.h b/libxml++/nodes/processinginstructionnode.h index beb20ee3..69ae17f1 100644 --- a/libxml++/nodes/processinginstructionnode.h +++ b/libxml++/nodes/processinginstructionnode.h @@ -12,7 +12,7 @@ namespace xmlpp { -class ProcessingInstructionNode : public ContentNode +class LIBXMLPP_API ProcessingInstructionNode : public ContentNode { public: explicit ProcessingInstructionNode(_xmlNode* node); diff --git a/libxml++/nodes/textnode.cc b/libxml++/nodes/textnode.cc index b640e024..f686fb23 100644 --- a/libxml++/nodes/textnode.cc +++ b/libxml++/nodes/textnode.cc @@ -5,13 +5,12 @@ */ #include -#include #include namespace xmlpp { - + TextNode::TextNode(xmlNode* node) : ContentNode(node) {} diff --git a/libxml++/nodes/textnode.h b/libxml++/nodes/textnode.h index b88f8bed..de36ad55 100644 --- a/libxml++/nodes/textnode.h +++ b/libxml++/nodes/textnode.h @@ -12,9 +12,9 @@ namespace xmlpp { -/** Text Node. This will be instantiated by the parser. +/** Text node. This will be instantiated by the parser. */ -class TextNode : public ContentNode +class LIBXMLPP_API TextNode : public ContentNode { public: explicit TextNode(_xmlNode* node); diff --git a/libxml++/nodes/xincludeend.h b/libxml++/nodes/xincludeend.h index 3b71b2da..a3951127 100644 --- a/libxml++/nodes/xincludeend.h +++ b/libxml++/nodes/xincludeend.h @@ -24,12 +24,12 @@ namespace xmlpp { -/** XIncludeEnd node. +/** %XIncludeEnd node. * This will be instantiated by xmlpp::Document::process_xinclude(). * * @newin{2,36} */ -class XIncludeEnd : public Node +class LIBXMLPP_API XIncludeEnd : public Node { public: explicit XIncludeEnd(_xmlNode* node); diff --git a/libxml++/nodes/xincludestart.h b/libxml++/nodes/xincludestart.h index d11c47f5..c97438a3 100644 --- a/libxml++/nodes/xincludestart.h +++ b/libxml++/nodes/xincludestart.h @@ -24,12 +24,12 @@ namespace xmlpp { -/** XIncludeStart node. +/** %XIncludeStart node. * This will be instantiated by xmlpp::Document::process_xinclude(). * * @newin{2,36} */ -class XIncludeStart : public Node +class LIBXMLPP_API XIncludeStart : public Node { public: explicit XIncludeStart(_xmlNode* node); diff --git a/libxml++/noncopyable.cc b/libxml++/noncopyable.cc index f809f480..76980e1d 100644 --- a/libxml++/noncopyable.cc +++ b/libxml++/noncopyable.cc @@ -10,7 +10,7 @@ namespace xmlpp { -NonCopyable::NonCopyable() +NonCopyable::NonCopyable() noexcept { } diff --git a/libxml++/noncopyable.h b/libxml++/noncopyable.h index d82395a1..667fe371 100644 --- a/libxml++/noncopyable.h +++ b/libxml++/noncopyable.h @@ -8,20 +8,24 @@ #ifndef __LIBXMLPP_NONCOPYABLE_H #define __LIBXMLPP_NONCOPYABLE_H +#include + namespace xmlpp { -/** - * A base for classes which cannot be copied. +/** A base for classes which cannot be copied or moved. */ -class NonCopyable +class LIBXMLPP_API NonCopyable { -protected: - NonCopyable(); - virtual ~NonCopyable(); - +public: NonCopyable(const NonCopyable&) = delete; NonCopyable& operator=(const NonCopyable&) = delete; + NonCopyable(NonCopyable&&) = delete; + NonCopyable& operator=(NonCopyable&&) = delete; + +protected: + NonCopyable() noexcept; + virtual ~NonCopyable(); }; } // namespace xmlpp diff --git a/libxml++/parsers/domparser.cc b/libxml++/parsers/domparser.cc index e8ba7ede..e3f03ec3 100644 --- a/libxml++/parsers/domparser.cc +++ b/libxml++/parsers/domparser.cc @@ -12,10 +12,24 @@ #include "libxml++/keepblanks.h" #include "libxml++/exceptions/internal_error.h" #include //For xmlCreateFileParserCtxt(). +#include #include #include +namespace { + extern "C" { + static int _io_read_callback(void * context, + char * buffer, + int len) + { + auto in = static_cast(context); + in->read(buffer, len); + return in->gcount(); + } + } +} + namespace xmlpp { @@ -26,7 +40,7 @@ DomParser::DomParser() doc_ = new Document(); } -DomParser::DomParser(const Glib::ustring& filename, bool validate) +DomParser::DomParser(const std::string& filename, bool validate) : doc_(nullptr) { set_validate(validate); @@ -34,11 +48,31 @@ DomParser::DomParser(const Glib::ustring& filename, bool validate) } DomParser::~DomParser() -{ +{ release_underlying(); } -void DomParser::parse_file(const Glib::ustring& filename) +void DomParser::set_xinclude_options(bool process_xinclude, + bool generate_xinclude_nodes, bool fixup_base_uris) noexcept +{ + xinclude_options_ = 0; + if (process_xinclude) + xinclude_options_ |= XML_PARSE_XINCLUDE; + if (!generate_xinclude_nodes) + xinclude_options_ |= XML_PARSE_NOXINCNODE; + if (!fixup_base_uris) + xinclude_options_ |= XML_PARSE_NOBASEFIX; +} + +void DomParser::get_xinclude_options(bool& process_xinclude, + bool& generate_xinclude_nodes, bool& fixup_base_uris) const noexcept +{ + process_xinclude = (xinclude_options_ & XML_PARSE_XINCLUDE) != 0; + generate_xinclude_nodes = (xinclude_options_ & XML_PARSE_NOXINCNODE) == 0; + fixup_base_uris = (xinclude_options_ & XML_PARSE_NOBASEFIX) == 0; +} + +void DomParser::parse_file(const std::string& filename) { release_underlying(); //Free any existing document. @@ -79,9 +113,9 @@ void DomParser::parse_memory_raw(const unsigned char* contents, size_type bytes_ parse_context(); } -void DomParser::parse_memory(const Glib::ustring& contents) +void DomParser::parse_memory(const ustring& contents) { - parse_memory_raw((const unsigned char*)contents.c_str(), contents.bytes()); + parse_memory_raw((const unsigned char*)contents.c_str(), contents.size()); } void DomParser::parse_context() @@ -120,13 +154,36 @@ void DomParser::parse_context() throw parse_error(error_str); } + check_xinclude_and_finish_parsing(); +} + +void DomParser::check_xinclude_and_finish_parsing() +{ + int set_options = 0; + int clear_options = 0; + get_parser_options(set_options, clear_options); + + int options = xinclude_options_; + // Turn on/off any xinclude options. + options |= set_options; + options &= ~clear_options; + + if (options & XML_PARSE_XINCLUDE) + { + const int n_substitutions = xmlXIncludeProcessFlags(context_->myDoc, options); + if (n_substitutions < 0) + { + throw parse_error("Couldn't process XInclude\n" + format_xml_error()); + } + } + doc_ = new Document(context_->myDoc); - // This is to indicate to release_underlying that we took the + // This is to indicate to release_underlying() that we took the // ownership on the doc. context_->myDoc = nullptr; - //Free the parse context, but keep the document alive so people can navigate the DOM tree: - //TODO: Why not keep the context alive too? + // Free the parser context because it's not needed anymore, + // but keep the document alive so people can navigate the DOM tree: Parser::release_underlying(); } @@ -137,71 +194,20 @@ void DomParser::parse_stream(std::istream& in) KeepBlanks k(KeepBlanks::Default); xmlResetLastError(); - context_ = xmlCreatePushParserCtxt( - 0, // Setting those two parameters to 0 force the parser - 0, // to create a document while parsing. - 0, // chunk - 0, // size - 0); // no filename for fetching external entities + context_ = xmlCreateIOParserCtxt( + nullptr, // Setting those two parameters to nullptr force the parser + nullptr, // to create a document while parsing. + _io_read_callback, + nullptr, // inputCloseCallback + &in, + XML_CHAR_ENCODING_NONE); if(!context_) { throw internal_error("Could not create parser context\n" + format_xml_error()); } - initialize_context(); - - //TODO: Shouldn't we use a Glib::ustring here, and some alternative to std::getline()? - int firstParseError = XML_ERR_OK; - std::string line; - while(std::getline(in, line)) - { - // since getline does not get the line separator, we have to add it since the parser cares - // about layout in certain cases. - line += '\n'; - - const int parseError = xmlParseChunk(context_, line.c_str(), - line.size() /* This is a std::string, not a ustring, so this is the number of bytes. */, 0); - - // Save the first error code if any, but read on. - // More errors might be reported and then thrown by check_for_exception(). - if (parseError != XML_ERR_OK && firstParseError == XML_ERR_OK) - firstParseError = parseError; - } - - const int parseError = xmlParseChunk(context_, 0, 0, 1 /* last chunk */); - if (parseError != XML_ERR_OK && firstParseError == XML_ERR_OK) - firstParseError = parseError; - - try - { - check_for_exception(); - } - catch (...) - { - release_underlying(); //Free doc_ and context_ - throw; // re-throw exception - } - - auto error_str = format_xml_parser_error(context_); - if (error_str.empty() && firstParseError != XML_ERR_OK) - error_str = "Error code from xmlParseChunk(): " + Glib::ustring::format(firstParseError); - - if(!error_str.empty()) - { - release_underlying(); //Free doc_ and context_ - throw parse_error(error_str); - } - - doc_ = new Document(context_->myDoc); - // This is to indicate to release_underlying that we took the - // ownership on the doc. - context_->myDoc = nullptr; - - - //Free the parse context, but keep the document alive so people can navigate the DOM tree: - //TODO: Why not keep the context alive too? - Parser::release_underlying(); + parse_context(); } void DomParser::release_underlying() @@ -215,17 +221,17 @@ void DomParser::release_underlying() Parser::release_underlying(); } -DomParser::operator bool() const +DomParser::operator bool() const noexcept { return doc_ != nullptr; } -Document* DomParser::get_document() +Document* DomParser::get_document() noexcept { return doc_; } -const Document* DomParser::get_document() const +const Document* DomParser::get_document() const noexcept { return doc_; } diff --git a/libxml++/parsers/domparser.h b/libxml++/parsers/domparser.h index f90aa7ad..6c40ceb4 100644 --- a/libxml++/parsers/domparser.h +++ b/libxml++/parsers/domparser.h @@ -8,13 +8,12 @@ #define __LIBXMLPP_PARSERS_DOMPARSER_H #include -#include #include namespace xmlpp { /** DOM XML parser. - * + * DOM = %Document Object Model */ class DomParser : public Parser { @@ -22,17 +21,45 @@ class DomParser : public Parser /** Create a parser with an empty document. * @throws xmlpp::internal_error If an empty document can't be created. */ - DomParser(); + LIBXMLPP_API DomParser(); /** Instantiate the parser and parse a document immediately. * @param filename The path to the file. - * @param validate Whether the parser should validate the XML. + * @param validate Whether the parser should validate the XML. * @throws xmlpp::internal_error * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - explicit DomParser(const Glib::ustring& filename, bool validate = false); - ~DomParser() override; + LIBXMLPP_API + explicit DomParser(const std::string& filename, bool validate = false); + LIBXMLPP_API ~DomParser() override; + + /** Set whether and how the parser will perform XInclude substitution. + * + * @newin{3,2} + * + * @param process_xinclude Do XInclude substitution on the XML document. + * If false, the other parameters have no effect. + * @param generate_xinclude_nodes Generate XIncludeStart and XIncludeEnd nodes. + * @param fixup_base_uris Add or replace xml:base attributes in included element + * nodes, if necessary to preserve the target of relative URIs. + */ + LIBXMLPP_API + void set_xinclude_options(bool process_xinclude = true, + bool generate_xinclude_nodes = true, bool fixup_base_uris = true) noexcept; + + /** Get whether and how the parser will perform XInclude substitution. + * + * @newin{3,2} + * + * @param[out] process_xinclude Do XInclude substitution on the XML document. + * @param[out] generate_xinclude_nodes Generate XIncludeStart and XIncludeEnd nodes. + * @param[out] fixup_base_uris Add or replace xml:base attributes in included element + * nodes, if necessary to preserve the target of relative URIs. + */ + LIBXMLPP_API + void get_xinclude_options(bool& process_xinclude, + bool& generate_xinclude_nodes, bool& fixup_base_uris) const noexcept; /** Parse an XML document from a file. * If the parser already contains a document, that document and all its nodes @@ -42,7 +69,8 @@ class DomParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_file(const Glib::ustring& filename) override; + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse an XML document from a string. * If the parser already contains a document, that document and all its nodes @@ -52,8 +80,9 @@ class DomParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_memory(const Glib::ustring& contents) override; - + LIBXMLPP_API + void parse_memory(const ustring& contents) override; + /** Parse an XML document from raw memory. * If the parser already contains a document, that document and all its nodes * are deleted. @@ -63,7 +92,8 @@ class DomParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_memory_raw(const unsigned char* contents, size_type bytes_count); + LIBXMLPP_API + void parse_memory_raw(const unsigned char* contents, size_type bytes_count) override; /** Parse an XML document from a stream. * If the parser already contains a document, that document and all its nodes @@ -73,28 +103,36 @@ class DomParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ + LIBXMLPP_API void parse_stream(std::istream& in) override; /** Test whether a document has been parsed. */ - operator bool() const; - + LIBXMLPP_API + explicit operator bool() const noexcept; + /** Get the parsed document. - * @returns A pointer to the parsed document, or 0. + * @returns A pointer to the parsed document, or nullptr. */ - Document* get_document(); + LIBXMLPP_API + Document* get_document() noexcept; /** Get the parsed document. - * @returns A pointer to the parsed document, or 0. + * @returns A pointer to the parsed document, or nullptr. */ - const Document* get_document() const; - + LIBXMLPP_API + const Document* get_document() const noexcept; + protected: - //TODO: Remove the virtual when we can break ABI? - virtual void parse_context(); + LIBXMLPP_API + void parse_context(); + LIBXMLPP_API + void check_xinclude_and_finish_parsing(); + LIBXMLPP_API void release_underlying() override; - + + int xinclude_options_ = 0; Document* doc_; }; diff --git a/libxml++/parsers/parser.cc b/libxml++/parsers/parser.cc index bd3865c8..398fc091 100644 --- a/libxml++/parsers/parser.cc +++ b/libxml++/parsers/parser.cc @@ -4,150 +4,153 @@ * included with libxml++ as the file COPYING. */ -// Include glibmm/threads.h first. It must be the first file to include glib.h, -// because it temporarily undefines G_DISABLE_DEPRECATED while it includes glib.h. -#include // For Glib::Threads::Mutex. Needed until the next API/ABI break. +// Direct access to xmlParserCtxt::options and xmlParserCtxt::linenumbers +// is deprecated since libxml2 2.14.0. +// xmlCtxtGetOptions() is new in libxml2 2.14.0. +// Ignore deprecations here. +#define XML_DEPRECATED_MEMBER #include "libxml++/exceptions/wrapped_exception.h" #include "libxml++/parsers/parser.h" #include -#include //For unique_ptr. -#include +namespace +{ +// C++ linkage +using ErrorOrWarningFuncType = void (*)(bool parser, bool error, void* ctx, + const char* msg, va_list var_args); +ErrorOrWarningFuncType p_callback_error_or_warning; -//TODO: See several TODOs in parser.h for changes at the next API/ABI break. +extern "C" +{ +static void c_callback_parser_error(void* ctx, const char* msg, ...) +{ + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(true, true, ctx, msg, var_args); + va_end(var_args); +} -namespace // anonymous +static void c_callback_parser_warning(void* ctx, const char* msg, ...) +{ + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(true, false, ctx, msg, var_args); + va_end(var_args); +} +static void c_callback_validity_error(void* ctx, const char* msg, ...) { -// These are new data members that can't be added to xmlpp::Parser now, -// because it would break ABI. -struct ExtraParserData + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(false, true, ctx, msg, var_args); + va_end(var_args); +} + +static void c_callback_validity_warning(void* ctx, const char* msg, ...) { - // Strange default values for throw_*_messages chosen for backward compatibility. - ExtraParserData() - : throw_parser_messages_(false), throw_validity_messages_(true), + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(false, false, ctx, msg, var_args); + va_end(var_args); +} +} // extern "C" +} // anonymous namespace + +namespace xmlpp +{ + +struct Parser::Impl +{ + Impl() + : + throw_messages_(true), validate_(false), substitute_entities_(false), include_default_attributes_(false), set_options_(0), clear_options_(0) {} - Glib::ustring parser_error_; - Glib::ustring parser_warning_; - bool throw_parser_messages_; - bool throw_validity_messages_; + // Built gradually - used in an exception at the end of parsing. + ustring parser_error_; + ustring parser_warning_; + ustring validate_error_; + ustring validate_warning_; + + bool throw_messages_; + bool validate_; + bool substitute_entities_; bool include_default_attributes_; int set_options_; int clear_options_; }; -std::map extra_parser_data; -// Different Parser instances may run in different threads. -// Accesses to extra_parser_data must be thread-safe. -Glib::Threads::Mutex extra_parser_data_mutex; - -void on_parser_error(const xmlpp::Parser* parser, const Glib::ustring& message) -{ - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - //Throw an exception later when the whole message has been received: - extra_parser_data[parser].parser_error_ += message; -} - -void on_parser_warning(const xmlpp::Parser* parser, const Glib::ustring& message) -{ - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - //Throw an exception later when the whole message has been received: - extra_parser_data[parser].parser_warning_ += message; -} -} // anonymous - -namespace xmlpp { - Parser::Parser() -: context_(nullptr), exception_(nullptr), validate_(false), substitute_entities_(false) //See doxygen comment on set_substiute_entities(). +: context_(nullptr), exception_(nullptr), pimpl_(new Impl) { - } Parser::~Parser() { release_underlying(); - delete exception_; - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - extra_parser_data.erase(this); } -void Parser::set_validate(bool val) +void Parser::set_validate(bool val) noexcept { - validate_ = val; + pimpl_->validate_ = val; } -bool Parser::get_validate() const +bool Parser::get_validate() const noexcept { - return validate_; + return pimpl_->validate_; } -void Parser::set_substitute_entities(bool val) +void Parser::set_substitute_entities(bool val) noexcept { - substitute_entities_ = val; + pimpl_->substitute_entities_ = val; } -bool Parser::get_substitute_entities() const +bool Parser::get_substitute_entities() const noexcept { - return substitute_entities_; + return pimpl_->substitute_entities_; } -void Parser::set_throw_messages(bool val) +void Parser::set_throw_messages(bool val) noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - extra_parser_data[this].throw_parser_messages_ = val; - extra_parser_data[this].throw_validity_messages_ = val; + pimpl_->throw_messages_ = val; } -bool Parser::get_throw_messages() const +bool Parser::get_throw_messages() const noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - return extra_parser_data[this].throw_parser_messages_; + return pimpl_->throw_messages_; } -void Parser::set_include_default_attributes(bool val) +void Parser::set_include_default_attributes(bool val) noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - extra_parser_data[this].include_default_attributes_ = val; + pimpl_->include_default_attributes_ = val; } -bool Parser::get_include_default_attributes() +bool Parser::get_include_default_attributes() const noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - return extra_parser_data[this].include_default_attributes_; + return pimpl_->include_default_attributes_; } -void Parser::set_parser_options(int set_options, int clear_options) +void Parser::set_parser_options(int set_options, int clear_options) noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - extra_parser_data[this].set_options_ = set_options; - extra_parser_data[this].clear_options_ = clear_options; + pimpl_->set_options_ = set_options; + pimpl_->clear_options_ = clear_options; } -void Parser::get_parser_options(int& set_options, int& clear_options) +void Parser::get_parser_options(int& set_options, int& clear_options) const noexcept { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - set_options = extra_parser_data[this].set_options_; - clear_options = extra_parser_data[this].clear_options_; + set_options = pimpl_->set_options_; + clear_options = pimpl_->clear_options_; } void Parser::initialize_context() { - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - //Clear these temporary buffers: - extra_parser_data[this].parser_error_.erase(); - extra_parser_data[this].parser_warning_.erase(); - validate_error_.erase(); - validate_warning_.erase(); - - // Take a copy of the extra data, so we don't have to access - // the extra_parser_data map more than necessary. - const auto extra_parser_data_this = extra_parser_data[this]; - lock.release(); + pimpl_->parser_error_.erase(); + pimpl_->parser_warning_.erase(); + pimpl_->validate_error_.erase(); + pimpl_->validate_warning_.erase(); //Disactivate any non-standards-compliant libxml1 features. //These are disactivated by default, but if we don't deactivate them for each context @@ -157,44 +160,44 @@ void Parser::initialize_context() //Turn on/off validation, entity substitution and default attribute inclusion. int options = context_->options; - if (validate_) + if (pimpl_->validate_) options |= XML_PARSE_DTDVALID; else options &= ~XML_PARSE_DTDVALID; - if (substitute_entities_) + if (pimpl_->substitute_entities_) options |= XML_PARSE_NOENT; else options &= ~XML_PARSE_NOENT; - if (extra_parser_data_this.include_default_attributes_) + if (pimpl_->include_default_attributes_) options |= XML_PARSE_DTDATTR; else options &= ~XML_PARSE_DTDATTR; //Turn on/off any parser options. - options |= extra_parser_data_this.set_options_; - options &= ~extra_parser_data_this.clear_options_; + options |= pimpl_->set_options_; + options &= ~pimpl_->clear_options_; xmlCtxtUseOptions(context_, options); - if (context_->sax && extra_parser_data_this.throw_parser_messages_) + if (context_->sax && pimpl_->throw_messages_) { //Tell the parser context about the callbacks. - context_->sax->fatalError = &callback_parser_error; - context_->sax->error = &callback_parser_error; - context_->sax->warning = &callback_parser_warning; + context_->sax->fatalError = get_callback_parser_error_cfunc(); + context_->sax->error = get_callback_parser_error_cfunc(); + context_->sax->warning = get_callback_parser_warning_cfunc(); } - if (extra_parser_data_this.throw_validity_messages_) + if (pimpl_->throw_messages_) { //Tell the validity context about the callbacks: //(These are only called if validation is on - see above) - context_->vctxt.error = &callback_validity_error; - context_->vctxt.warning = &callback_validity_warning; + context_->vctxt.error = get_callback_validity_error_cfunc(); + context_->vctxt.warning = get_callback_validity_warning_cfunc(); } - //Allow the callback_validity_*() methods to retrieve the C++ instance: + //Allow callback_error_or_warning() to retrieve the C++ instance: context_->_private = this; } @@ -203,7 +206,7 @@ void Parser::release_underlying() if(context_) { context_->_private = nullptr; //Not really necessary. - + if( context_->myDoc != nullptr ) { xmlFreeDoc(context_->myDoc); @@ -214,107 +217,157 @@ void Parser::release_underlying() } } -void Parser::on_validity_error(const Glib::ustring& message) +void Parser::on_parser_error(const ustring& message) { //Throw an exception later when the whole message has been received: - validate_error_ += message; + pimpl_->parser_error_ += message; } -void Parser::on_validity_warning(const Glib::ustring& message) +void Parser::on_parser_warning(const ustring& message) +{ + //Throw an exception later when the whole message has been received: + pimpl_->parser_warning_ += message; +} +void Parser::on_validity_error(const ustring& message) { //Throw an exception later when the whole message has been received: - validate_warning_ += message; + pimpl_->validate_error_ += message; } -void Parser::check_for_validity_messages() // Also checks parser messages +void Parser::on_validity_warning(const ustring& message) { - Glib::ustring msg(exception_ ? exception_->what() : ""); + //Throw an exception later when the whole message has been received: + pimpl_->validate_warning_ += message; +} + +void Parser::check_for_error_and_warning_messages() +{ + ustring msg(exception_ ? exception_->what() : ""); bool parser_msg = false; bool validity_msg = false; - Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex); - if (!extra_parser_data[this].parser_error_.empty()) + if (!pimpl_->parser_error_.empty()) { parser_msg = true; - msg += "\nParser error:\n" + extra_parser_data[this].parser_error_; - extra_parser_data[this].parser_error_.erase(); + msg += "\nParser error:\n" + pimpl_->parser_error_; + pimpl_->parser_error_.erase(); } - if (!extra_parser_data[this].parser_warning_.empty()) + if (!pimpl_->parser_warning_.empty()) { parser_msg = true; - msg += "\nParser warning:\n" + extra_parser_data[this].parser_warning_; - extra_parser_data[this].parser_warning_.erase(); + msg += "\nParser warning:\n" + pimpl_->parser_warning_; + pimpl_->parser_warning_.erase(); } - if (!validate_error_.empty()) + if (!pimpl_->validate_error_.empty()) { validity_msg = true; - msg += "\nValidity error:\n" + validate_error_; - validate_error_.erase(); + msg += "\nValidity error:\n" + pimpl_->validate_error_; + pimpl_->validate_error_.erase(); } - if (!validate_warning_.empty()) + if (!pimpl_->validate_warning_.empty()) { validity_msg = true; - msg += "\nValidity warning:\n" + validate_warning_; - validate_warning_.erase(); + msg += "\nValidity warning:\n" + pimpl_->validate_warning_; + pimpl_->validate_warning_.erase(); } - if (parser_msg || validity_msg) - { - delete exception_; - if (validity_msg) - exception_ = new validity_error(msg); - else - exception_ = new parse_error(msg); - } + if (validity_msg) + exception_ = std::make_unique(msg); + else if (parser_msg) + exception_ = std::make_unique(msg); } - + +#ifndef LIBXMLXX_DISABLE_DEPRECATED +//static void Parser::callback_parser_error(void* ctx, const char* msg, ...) { va_list var_args; va_start(var_args, msg); - callback_error_or_warning(MsgParserError, ctx, msg, var_args); + callback_error_or_warning(MsgType::ParserError, ctx, msg, var_args); va_end(var_args); } +//static void Parser::callback_parser_warning(void* ctx, const char* msg, ...) { va_list var_args; va_start(var_args, msg); - callback_error_or_warning(MsgParserWarning, ctx, msg, var_args); + callback_error_or_warning(MsgType::ParserWarning, ctx, msg, var_args); va_end(var_args); } +//static void Parser::callback_validity_error(void* ctx, const char* msg, ...) { va_list var_args; va_start(var_args, msg); - callback_error_or_warning(MsgValidityError, ctx, msg, var_args); + callback_error_or_warning(MsgType::ValidityError, ctx, msg, var_args); va_end(var_args); } +//static void Parser::callback_validity_warning(void* ctx, const char* msg, ...) { va_list var_args; va_start(var_args, msg); - callback_error_or_warning(MsgValidityWarning, ctx, msg, var_args); + callback_error_or_warning(MsgType::ValidityWarning, ctx, msg, var_args); va_end(var_args); } +//static void Parser::callback_error_or_warning(MsgType msg_type, void* ctx, const char* msg, va_list var_args) +{ + const bool is_parser = (msg_type == MsgType::ParserError) || (msg_type == MsgType::ParserWarning); + const bool is_error = (msg_type == MsgType::ParserError) || (msg_type == MsgType::ValidityError); + callback_error_or_warning(is_parser, is_error, ctx, msg, var_args); +} +#endif // LIBXMLXX_DISABLE_DEPRECATED + +//static +ParserCallbackCFuncType Parser::get_callback_parser_error_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_parser_error; +} + +//static +ParserCallbackCFuncType Parser::get_callback_parser_warning_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_parser_warning; +} + +//static +ParserCallbackCFuncType Parser::get_callback_validity_error_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_validity_error; +} + +//static +ParserCallbackCFuncType Parser::get_callback_validity_warning_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_validity_warning; +} + +//static +void Parser::callback_error_or_warning(bool is_parser, bool is_error, void* ctx, + const char* msg, va_list var_args) { //See xmlHTMLValidityError() in xmllint.c in libxml for more about this: - + auto context = (xmlParserCtxtPtr)ctx; if(context) { auto parser = static_cast(context->_private); if(parser) { - auto ubuff = format_xml_error(&context->lastError); + auto ubuff = format_xml_error(xmlCtxtGetLastError(context)); if (ubuff.empty()) { // Usually the result of formatting var_args with the format string msg @@ -323,48 +376,62 @@ void Parser::callback_error_or_warning(MsgType msg_type, void* ctx, // returns an error message (as it usually does). //Convert the ... to a string: - char buff[1024]; - - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, var_args); - ubuff = buff; + ubuff = format_printf_message(msg, var_args); } try { - switch (msg_type) + if (is_parser) + { + if (is_error) + parser->on_parser_error(ubuff); + else + parser->on_parser_warning(ubuff); + } + else // validator { - case MsgParserError: - on_parser_error(parser, ubuff); - break; - case MsgParserWarning: - on_parser_warning(parser, ubuff); - break; - case MsgValidityError: + if (is_error) parser->on_validity_error(ubuff); - break; - case MsgValidityWarning: + else parser->on_validity_warning(ubuff); - break; } } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } } } -void Parser::handleException(const exception& e) +void Parser::handle_exception() { - delete exception_; - exception_ = e.Clone(); + try + { + throw; // Re-throw current exception + } + catch (const exception& e) + { + exception_.reset(e.clone()); + } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR + catch (...) + { + exception_ = std::make_unique(std::current_exception()); + } +#else + catch (const std::exception& e) + { + exception_.reset(new exception(e.what())); + } + catch (...) + { + exception_.reset(new exception("An exception was thrown that is not derived from std::exception or xmlpp::exception.\n" + "It could not be caught and rethrown because this platform does not support std::exception_ptr.")); + } +#endif - if(context_) + if (context_) xmlStopParser(context_); //release_underlying(); @@ -372,15 +439,13 @@ void Parser::handleException(const exception& e) void Parser::check_for_exception() { - check_for_validity_messages(); - - if(exception_) + check_for_error_and_warning_messages(); + + if (exception_) { - std::unique_ptr tmp(exception_); - exception_ = nullptr; - tmp->Raise(); + std::unique_ptr tmp(std::move(exception_)); + tmp->raise(); } } } // namespace xmlpp - diff --git a/libxml++/parsers/parser.h b/libxml++/parsers/parser.h index 96034af8..f99ebaba 100644 --- a/libxml++/parsers/parser.h +++ b/libxml++/parsers/parser.h @@ -7,16 +7,14 @@ #ifndef __LIBXMLPP_PARSER_H #define __LIBXMLPP_PARSER_H -#ifdef _MSC_VER //Ignore warnings about the Visual C++ Bug, where we can not do anything -#pragma warning (disable : 4786) -#endif - #include #include #include +#include #include -#include //For va_list. +#include // va_list +#include // std::unique_ptr #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { @@ -26,65 +24,84 @@ extern "C" { namespace xmlpp { +extern "C" { + /** Type of function pointer to callback function with C linkage. + * @newin{5,2} + */ + using ParserCallbackCFuncType = void (*)(void* ctx, const char* msg, ...); +} + /** XML parser. * + * Abstract base class for DOM parser and SAX parser. */ -class Parser : NonCopyable +class Parser : public NonCopyable { public: - Parser(); - ~Parser() override; + LIBXMLPP_API Parser(); + LIBXMLPP_API ~Parser() override; - typedef unsigned int size_type; - - //TODO: Remove virtuals when we can break ABI. + using size_type = unsigned int; /** By default, the parser will not validate the XML file. * @param val Whether the document should be validated. */ - virtual void set_validate(bool val = true); + LIBXMLPP_API + void set_validate(bool val = true) noexcept; /** See set_validate(). * @returns Whether the parser will validate the XML file. */ - virtual bool get_validate() const; + LIBXMLPP_API + bool get_validate() const noexcept; /** Set whether the parser will automatically substitute entity references with the text of the entities' definitions. * For instance, this affects the text returned by ContentNode::get_content(). * By default, the parser will not substitute entities, so that you do not lose the entity reference information. * @param val Whether entities will be substitued. */ - virtual void set_substitute_entities(bool val = true); + LIBXMLPP_API + void set_substitute_entities(bool val = true) noexcept; /** See set_substitute_entities(). * @returns Whether entities will be substituted during parsing. */ - virtual bool get_substitute_entities() const; + LIBXMLPP_API + bool get_substitute_entities() const noexcept; /** Set whether the parser will collect and throw error and warning messages. + * * If messages are collected, they are included in an exception thrown at the - * end of parsing. If the messages are not collected, they are written on - * stderr. The messages written on stderr are slightly different, and may - * be preferred in a program started from the command-line. + * end of parsing. + * + * - DOM parser + * + * If the messages are not collected, they are written on stderr. + * The messages written on stderr are slightly different, and may be + * preferred in a program started from the command-line. The default, if + * set_throw_messages() is not called, is to collect and throw messages. * - * The default, if set_throw_messages() is not called, is to collect and throw - * only messages from validation. Other messages are written to stderr. - * This is for backward compatibility, and may change in the future. + * - SAX parser + * + * If the messages are not collected, the error handling on_*() methods in + * the user's SAX parser subclass are called. This is the default, if + * set_throw_messages() is not called. * * @newin{2,36} * * @param val Whether messages will be collected and thrown in an exception. */ - void set_throw_messages(bool val = true); + LIBXMLPP_API + void set_throw_messages(bool val = true) noexcept; /** See set_throw_messages(). * * @newin{2,36} * * @returns Whether messages will be collected and thrown in an exception. - * The default with only validation messages thrown is returned as false. */ - bool get_throw_messages() const; + LIBXMLPP_API + bool get_throw_messages() const noexcept; /** Set whether default attribute values from the DTD shall be included in the node tree. * If set, attributes not assigned a value in the XML file, but with a default value @@ -96,7 +113,8 @@ class Parser : NonCopyable * * @param val Whether attributes with default values will be included in the node tree. */ - void set_include_default_attributes(bool val = true); + LIBXMLPP_API + void set_include_default_attributes(bool val = true) noexcept; /** See set_include_default_attributes(). * @@ -104,10 +122,13 @@ class Parser : NonCopyable * * @returns Whether attributes with default values will be included in the node tree. */ - bool get_include_default_attributes(); + LIBXMLPP_API + bool get_include_default_attributes() const noexcept; /** Set and/or clear parser option flags. - * See the libxml2 documentation, enum xmlParserOption, for a list of parser options. + * See the libxml2 documentation, + * [enum xmlParserOption](https://gnome.pages.gitlab.gnome.org/libxml2/devhelp/libxml2-parser.html#xmlParserOption), + * for a list of parser options. * This method overrides other methods that set parser options, such as set_validate(), * set_substitute_entities() and set_include_default_attributes(). Use set_parser_options() * only if no other method can set the parser options you want. @@ -118,88 +139,128 @@ class Parser : NonCopyable * @param clear_options Set bits correspond to flags that shall be cleared during parsing. * Bits that are set in neither @a set_options nor @a clear_options are not affected. */ - void set_parser_options(int set_options = 0, int clear_options = 0); + LIBXMLPP_API + void set_parser_options(int set_options = 0, int clear_options = 0) noexcept; /** See set_parser_options(). * * @newin{2,38} * - * @param [out] set_options Set bits correspond to flags that shall be set during parsing. - * @param [out] clear_options Set bits correspond to flags that shall be cleared during parsing. + * @param[out] set_options Set bits correspond to flags that shall be set during parsing. + * @param[out] clear_options Set bits correspond to flags that shall be cleared during parsing. * Bits that are set in neither @a set_options nor @a clear_options are not affected. */ - void get_parser_options(int& set_options, int& clear_options); + LIBXMLPP_API + void get_parser_options(int& set_options, int& clear_options) const noexcept; /** Parse an XML document from a file. * @throw exception * @param filename The path to the file. */ - virtual void parse_file(const Glib::ustring& filename) = 0; + LIBXMLPP_API + virtual void parse_file(const std::string& filename) = 0; + + /** Parse an XML document from raw memory. + * @throw exception + * @param contents The XML document as an array of bytes. + * @param bytes_count The number of bytes in the @a contents array. + */ + LIBXMLPP_API + virtual void parse_memory_raw(const unsigned char* contents, size_type bytes_count) = 0; - //TODO: In a future ABI-break, add a virtual void parse_memory_raw(const unsigned char* contents, size_type bytes_count); - /** Parse an XML document from a string. * @throw exception * @param contents The XML document as a string. */ - virtual void parse_memory(const Glib::ustring& contents) = 0; + LIBXMLPP_API + virtual void parse_memory(const ustring& contents) = 0; /** Parse an XML document from a stream. * @throw exception * @param in The stream. */ + LIBXMLPP_API virtual void parse_stream(std::istream& in) = 0; //TODO: Add stop_parser()/stop_parsing(), wrapping xmlStopParser()? protected: + LIBXMLPP_API virtual void initialize_context(); + LIBXMLPP_API virtual void release_underlying(); - //TODO: In a future ABI-break, add these virtual functions. - //virtual void on_parser_error(const Glib::ustring& message); - //virtual void on_parser_warning(const Glib::ustring& message); - virtual void on_validity_error(const Glib::ustring& message); - virtual void on_validity_warning(const Glib::ustring& message); - - virtual void handleException(const exception& e); + LIBXMLPP_API + virtual void on_parser_error(const ustring& message); + LIBXMLPP_API + virtual void on_parser_warning(const ustring& message); + LIBXMLPP_API + virtual void on_validity_error(const ustring& message); + LIBXMLPP_API + virtual void on_validity_warning(const ustring& message); + + /// To be called in an exception handler. + LIBXMLPP_API + virtual void handle_exception(); + LIBXMLPP_API virtual void check_for_exception(); - //TODO: In a future API/ABI-break, change the name of this function to - // something more appropriate, such as check_for_error_and_warning_messages. - virtual void check_for_validity_messages(); - + LIBXMLPP_API + virtual void check_for_error_and_warning_messages(); + +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** @deprecated Use get_callback_parser_error_cfunc() instead. */ + LIBXMLPP_API static void callback_parser_error(void* ctx, const char* msg, ...); + /** @deprecated Use get_callback_parser_warning_cfunc() instead. */ + LIBXMLPP_API static void callback_parser_warning(void* ctx, const char* msg, ...); + /** @deprecated Use get_callback_validity_error_cfunc() instead. */ + LIBXMLPP_API static void callback_validity_error(void* ctx, const char* msg, ...); + /** @deprecated Use get_callback_validity_warning_cfunc() instead. */ + LIBXMLPP_API static void callback_validity_warning(void* ctx, const char* msg, ...); - enum MsgType + /** @deprecated */ + enum class MsgType { - MsgParserError, - MsgParserWarning, - MsgValidityError, - MsgValidityWarning + ParserError, + ParserWarning, + ValidityError, + ValidityWarning }; + /** @deprecated Use the other callback_error_or_warning() overload instead. */ + LIBXMLPP_API static void callback_error_or_warning(MsgType msg_type, void* ctx, const char* msg, va_list var_args); +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** @newin{5,2} */ + LIBXMLPP_API + static ParserCallbackCFuncType get_callback_parser_error_cfunc(); + /** @newin{5,2} */ + LIBXMLPP_API + static ParserCallbackCFuncType get_callback_parser_warning_cfunc(); + /** @newin{5,2} */ + LIBXMLPP_API + static ParserCallbackCFuncType get_callback_validity_error_cfunc(); + /** @newin{5,2} */ + LIBXMLPP_API + static ParserCallbackCFuncType get_callback_validity_warning_cfunc(); + + /** @newin{5,2} */ + LIBXMLPP_API + static void callback_error_or_warning(bool is_parser, bool is_error, void* ctx, + const char* msg, va_list var_args); _xmlParserCtxt* context_; - exception* exception_; - //TODO: In a future ABI-break, add these members. - //bool throw_messages_; - //Glib::ustring parser_error_; - //Glib::ustring parser_warning_; - Glib::ustring validate_error_; - Glib::ustring validate_warning_; //Built gradually - used in an exception at the end of parsing. - - bool validate_; - bool substitute_entities_; - //TODO: In a future ABI-break, add these members. - //bool include_default_attributes_; - //int set_options_; - //int clear_options_; + std::unique_ptr exception_; + +private: + struct Impl; + std::unique_ptr pimpl_; }; /** Equivalent to Parser::parse_stream(). diff --git a/libxml++/parsers/saxparser.cc b/libxml++/parsers/saxparser.cc index 17531b20..2b0905a9 100644 --- a/libxml++/parsers/saxparser.cc +++ b/libxml++/parsers/saxparser.cc @@ -7,7 +7,6 @@ * 2002/01/21 Valentin Rusu - added CDATA handlers */ -#include "libxml++/exceptions/wrapped_exception.h" #include "libxml++/parsers/saxparser.h" #include "libxml++/nodes/element.h" #include "libxml++/keepblanks.h" @@ -18,6 +17,19 @@ #include //For va_list. #include +namespace { + extern "C" { + static int _io_read_callback(void * context, + char * buffer, + int len) + { + auto in = static_cast(context); + in->read(buffer, len); + return in->gcount(); + } + } +} + namespace xmlpp { struct SaxParserCallback @@ -40,43 +52,46 @@ struct SaxParserCallback SaxParser::SaxParser(bool use_get_entity) - : sax_handler_( new _xmlSAXHandler ) + : sax_handler_(new _xmlSAXHandler), entity_resolver_doc_(new Document) { xmlSAXHandler temp = { SaxParserCallback::internal_subset, - 0, // isStandalone - 0, // hasInternalSubset - 0, // hasExternalSubset - 0, // resolveEntity - use_get_entity ? SaxParserCallback::get_entity : 0, // getEntity + nullptr, // isStandalone + nullptr, // hasInternalSubset + nullptr, // hasExternalSubset + nullptr, // resolveEntity + use_get_entity ? SaxParserCallback::get_entity : nullptr, // getEntity SaxParserCallback::entity_decl, // entityDecl - 0, // notationDecl - 0, // attributeDecl - 0, // elementDecl - 0, // unparsedEntityDecl - 0, // setDocumentLocator + nullptr, // notationDecl + nullptr, // attributeDecl + nullptr, // elementDecl + nullptr, // unparsedEntityDecl + nullptr, // setDocumentLocator SaxParserCallback::start_document, // startDocument SaxParserCallback::end_document, // endDocument SaxParserCallback::start_element, // startElement SaxParserCallback::end_element, // endElement - 0, // reference + nullptr, // reference SaxParserCallback::characters, // characters - 0, // ignorableWhitespace - 0, // processingInstruction + nullptr, // ignorableWhitespace + nullptr, // processingInstruction SaxParserCallback::comment, // comment SaxParserCallback::warning, // warning SaxParserCallback::error, // error SaxParserCallback::fatal_error, // fatalError - 0, // getParameterEntity + nullptr, // getParameterEntity SaxParserCallback::cdata_block, // cdataBlock - 0, // externalSubset - 0, // initialized - 0, // private - 0, // startElementNs - 0, // endElementNs - 0, // serror + nullptr, // externalSubset + 0, // initialized + nullptr, // private + nullptr, // startElementNs + nullptr, // endElementNs + nullptr, // serror }; *sax_handler_ = temp; + + // The default action is to call on_warning(), on_error(), on_fatal_error(). + set_throw_messages(false); } SaxParser::~SaxParser() @@ -84,15 +99,15 @@ SaxParser::~SaxParser() release_underlying(); } -xmlEntityPtr SaxParser::on_get_entity(const Glib::ustring& name) +xmlEntityPtr SaxParser::on_get_entity(const ustring& name) { - return entity_resolver_doc_.get_entity(name); + return entity_resolver_doc_->get_entity(name); } -void SaxParser::on_entity_declaration(const Glib::ustring& name, XmlEntityType type, const Glib::ustring& publicId, const Glib::ustring& systemId, const Glib::ustring& content) +void SaxParser::on_entity_declaration(const ustring& name, XmlEntityType type, const ustring& publicId, const ustring& systemId, const ustring& content) { - entity_resolver_doc_.set_entity_declaration(name, type, publicId, systemId, content); -} + entity_resolver_doc_->set_entity_declaration(name, type, publicId, systemId, content); +} void SaxParser::on_start_document() { @@ -102,59 +117,51 @@ void SaxParser::on_end_document() { } -void SaxParser::on_start_element(const Glib::ustring& /* name */, const AttributeList& /* attributes */) +void SaxParser::on_start_element(const ustring& /* name */, const AttributeList& /* attributes */) { } -void SaxParser::on_end_element(const Glib::ustring& /* name */) +void SaxParser::on_end_element(const ustring& /* name */) { } -void SaxParser::on_characters(const Glib::ustring& /* text */) +void SaxParser::on_characters(const ustring& /* text */) { } -void SaxParser::on_comment(const Glib::ustring& /* text */) +void SaxParser::on_comment(const ustring& /* text */) { } -void SaxParser::on_warning(const Glib::ustring& /* text */) +void SaxParser::on_warning(const ustring& /* text */) { } -void SaxParser::on_error(const Glib::ustring& /* text */) +void SaxParser::on_error(const ustring& /* text */) { } -void SaxParser::on_fatal_error(const Glib::ustring& text) +void SaxParser::on_fatal_error(const ustring& text) { throw parse_error("Fatal error: " + text); } -void SaxParser::on_cdata_block(const Glib::ustring& /* text */) +void SaxParser::on_cdata_block(const ustring& /* text */) { } -void SaxParser::on_internal_subset(const Glib::ustring& name, - const Glib::ustring& publicId, - const Glib::ustring& systemId) +void SaxParser::on_internal_subset(const ustring& name, + const ustring& publicId, + const ustring& systemId) { - entity_resolver_doc_.set_internal_subset(name, publicId, systemId); + entity_resolver_doc_->set_internal_subset(name, publicId, systemId); } // implementation of this function is inspired by the SAX documentation by James Henstridge. // (http://www.daa.com.au/~james/gnome/xml-sax/implementing.html) void SaxParser::parse() { - //TODO If this is not the first parsing with this SaxParser, the xmlDoc object - // in entity_resolver_doc_ should be deleted and replaced by a new one. - // Otherwise entity declarations from a previous parsing may erroneously affect - // this parsing. This would be much easier if entity_resolver_doc_ were a - // std::unique_ptr, so the xmlpp::Document could be deleted and a new - // one created. A good place for such code would be in an overridden - // SaxParser::initialize_context(). It would be an ABI break. - if(!context_) { throw internal_error("Parser context not created."); @@ -165,7 +172,7 @@ void SaxParser::parse() xmlResetLastError(); initialize_context(); - + const int parseError = xmlParseDocument(context_); context_->sax = old_sax; @@ -184,7 +191,7 @@ void SaxParser::parse() } } -void SaxParser::parse_file(const Glib::ustring& filename) +void SaxParser::parse_file(const std::string& filename) { if(context_) { @@ -209,10 +216,10 @@ void SaxParser::parse_memory_raw(const unsigned char* contents, size_type bytes_ context_ = xmlCreateMemoryParserCtxt((const char*)contents, bytes_count); parse(); } - -void SaxParser::parse_memory(const Glib::ustring& contents) + +void SaxParser::parse_memory(const ustring& contents) { - parse_memory_raw((const unsigned char*)contents.c_str(), contents.bytes()); + parse_memory_raw((const unsigned char*)contents.c_str(), contents.size()); } void SaxParser::parse_stream(std::istream& in) @@ -223,68 +230,20 @@ void SaxParser::parse_stream(std::istream& in) } KeepBlanks k(KeepBlanks::Default); - xmlResetLastError(); - context_ = xmlCreatePushParserCtxt( + context_ = xmlCreateIOParserCtxt( sax_handler_.get(), - 0, // user_data - 0, // chunk - 0, // size - 0); // no filename for fetching external entities - - if(!context_) - { - throw internal_error("Could not create parser context\n" + format_xml_error()); - } - - initialize_context(); - - //TODO: Shouldn't we use a Glib::ustring here, and some alternative to std::getline()? - int firstParseError = XML_ERR_OK; - std::string line; - while( ( ! exception_ ) - && std::getline(in, line)) - { - // since getline does not get the line separator, we have to add it since the parser care - // about layout in certain cases. - line += '\n'; - - const int parseError = xmlParseChunk(context_, line.c_str(), - line.size() /* This is a std::string, not a ustring, so this is the number of bytes. */, - 0 /* don't terminate */); - - // Save the first error code if any, but read on. - // More errors might be reported and then thrown by check_for_exception(). - if (parseError != XML_ERR_OK && firstParseError == XML_ERR_OK) - firstParseError = parseError; - } - - if( ! exception_ ) - { - //This is called just to terminate parsing. - const int parseError = xmlParseChunk(context_, 0 /* chunk */, 0 /* size */, 1 /* terminate (1 or 0) */); - - if (parseError != XML_ERR_OK && firstParseError == XML_ERR_OK) - firstParseError = parseError; - } - - auto error_str = format_xml_parser_error(context_); - if (error_str.empty() && firstParseError != XML_ERR_OK) - error_str = "Error code from xmlParseChunk(): " + Glib::ustring::format(firstParseError); - - release_underlying(); // Free context_ - - check_for_exception(); - - if(!error_str.empty()) - { - throw parse_error(error_str); - } + nullptr, // user_data + _io_read_callback, + nullptr, // inputCloseCallback + &in, + XML_CHAR_ENCODING_NONE); + parse(); } -void SaxParser::parse_chunk(const Glib::ustring& chunk) +void SaxParser::parse_chunk(const ustring& chunk) { - parse_chunk_raw((const unsigned char*)chunk.c_str(), chunk.bytes()); + parse_chunk_raw((const unsigned char*)chunk.c_str(), chunk.size()); } void SaxParser::parse_chunk_raw(const unsigned char* contents, size_type bytes_count) @@ -296,10 +255,10 @@ void SaxParser::parse_chunk_raw(const unsigned char* contents, size_type bytes_c { context_ = xmlCreatePushParserCtxt( sax_handler_.get(), - 0, // user_data - 0, // chunk - 0, // size - 0); // no filename for fetching external entities + nullptr, // user_data + nullptr, // chunk + 0, // size + nullptr); // no filename for fetching external entities if(!context_) { @@ -309,27 +268,22 @@ void SaxParser::parse_chunk_raw(const unsigned char* contents, size_type bytes_c } else xmlCtxtResetLastError(context_); - + int parseError = XML_ERR_OK; - if(!exception_) + if (!exception_) parseError = xmlParseChunk(context_, (const char*)contents, bytes_count, 0 /* don't terminate */); check_for_exception(); auto error_str = format_xml_parser_error(context_); if (error_str.empty() && parseError != XML_ERR_OK) - error_str = "Error code from xmlParseChunk(): " + Glib::ustring::format(parseError); + error_str = "Error code from xmlParseChunk(): " + std::to_string(parseError); if(!error_str.empty()) { throw parse_error(error_str); } } -void SaxParser::release_underlying() -{ - Parser::release_underlying(); -} - void SaxParser::finish_chunk_parsing() { xmlResetLastError(); @@ -337,10 +291,10 @@ void SaxParser::finish_chunk_parsing() { context_ = xmlCreatePushParserCtxt( sax_handler_.get(), - 0, // this, // user_data - 0, // chunk - 0, // size - 0); // no filename for fetching external entities + nullptr, // user_data + nullptr, // chunk + 0, // size + nullptr); // no filename for fetching external entities if(!context_) { @@ -352,13 +306,13 @@ void SaxParser::finish_chunk_parsing() xmlCtxtResetLastError(context_); int parseError = XML_ERR_OK; - if(!exception_) + if (!exception_) //This is called just to terminate parsing. - parseError = xmlParseChunk(context_, 0 /* chunk */, 0 /* size */, 1 /* terminate (1 or 0) */); + parseError = xmlParseChunk(context_, nullptr /* chunk */, 0 /* size */, 1 /* terminate (1 or 0) */); auto error_str = format_xml_parser_error(context_); if (error_str.empty() && parseError != XML_ERR_OK) - error_str = "Error code from xmlParseChunk(): " + Glib::ustring::format(parseError); + error_str = "Error code from xmlParseChunk(): " + std::to_string(parseError); release_underlying(); // Free context_ @@ -370,6 +324,18 @@ void SaxParser::finish_chunk_parsing() } } +void SaxParser::release_underlying() +{ + Parser::release_underlying(); +} + +void SaxParser::initialize_context() +{ + Parser::initialize_context(); + // Start with an empty Document for entity resolution. + entity_resolver_doc_ = std::make_unique(); +} + xmlEntityPtr SaxParserCallback::get_entity(void* context, const xmlChar* name) { @@ -381,13 +347,9 @@ xmlEntityPtr SaxParserCallback::get_entity(void* context, const xmlChar* name) { result = parser->on_get_entity((const char*)name); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } return result; @@ -401,19 +363,15 @@ void SaxParserCallback::entity_decl(void* context, const xmlChar* name, int type try { parser->on_entity_declaration( - ( name ? Glib::ustring((const char*)name) : ""), + ( name ? ustring((const char*)name) : ""), static_cast(type), - ( publicId ? Glib::ustring((const char*)publicId) : ""), - ( systemId ? Glib::ustring((const char*)systemId) : ""), - ( content ? Glib::ustring((const char*)content) : "") ); - } - catch(const exception& e) - { - parser->handleException(e); + ( publicId ? ustring((const char*)publicId) : ""), + ( systemId ? ustring((const char*)systemId) : ""), + ( content ? ustring((const char*)content) : "") ); } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -426,13 +384,9 @@ void SaxParserCallback::start_document(void* context) { parser->on_start_document(); } - catch(const exception& e) - { - parser->handleException(e); - } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -441,20 +395,16 @@ void SaxParserCallback::end_document(void* context) auto the_context = static_cast<_xmlParserCtxt*>(context); auto parser = static_cast(the_context->_private); - if(parser->exception_) + if (parser->exception_) return; try { parser->on_end_document(); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -474,15 +424,11 @@ void SaxParserCallback::start_element(void* context, try { - parser->on_start_element(Glib::ustring((const char*) name), attributes); + parser->on_start_element(ustring((const char*) name), attributes); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -493,15 +439,11 @@ void SaxParserCallback::end_element(void* context, const xmlChar* name) try { - parser->on_end_element(Glib::ustring((const char*) name)); - } - catch(const exception& e) - { - parser->handleException(e); + parser->on_end_element(ustring((const char*) name)); } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -512,21 +454,17 @@ void SaxParserCallback::characters(void * context, const xmlChar* ch, int len) try { - // Here we force the use of Glib::ustring::ustring( InputIterator begin, InputIterator end ) - // instead of Glib::ustring::ustring( const char*, size_type ) because it + // Here we force the use of ustring::ustring( InputIterator begin, InputIterator end ) + // instead of ustring::ustring( const char*, size_type ) because it // expects the length of the string in characters, not in bytes. parser->on_characters( - Glib::ustring( + ustring( reinterpret_cast(ch), reinterpret_cast(ch + len) ) ); } - catch(const exception& e) - { - parser->handleException(e); - } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -537,15 +475,11 @@ void SaxParserCallback::comment(void* context, const xmlChar* value) try { - parser->on_comment(Glib::ustring((const char*) value)); + parser->on_comment(ustring((const char*) value)); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -555,23 +489,17 @@ void SaxParserCallback::warning(void* context, const char* fmt, ...) auto parser = static_cast(the_context->_private); va_list arg; - char buff[1024]; //TODO: Larger/Shared - va_start(arg, fmt); - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg); + const ustring buff = format_printf_message(fmt, arg); va_end(arg); try { - parser->on_warning(Glib::ustring(buff)); + parser->on_warning(buff); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -580,27 +508,21 @@ void SaxParserCallback::error(void* context, const char* fmt, ...) auto the_context = static_cast<_xmlParserCtxt*>(context); auto parser = static_cast(the_context->_private); - va_list arg; - char buff[1024]; //TODO: Larger/Shared - - if(parser->exception_) + if (parser->exception_) return; + va_list arg; va_start(arg, fmt); - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg); + const ustring buff = format_printf_message(fmt, arg); va_end(arg); try { - parser->on_error(Glib::ustring(buff)); + parser->on_error(buff); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -610,23 +532,17 @@ void SaxParserCallback::fatal_error(void* context, const char* fmt, ...) auto parser = static_cast(the_context->_private); va_list arg; - char buff[1024]; //TODO: Larger/Shared - va_start(arg, fmt); - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), fmt, arg); + const ustring buff = format_printf_message(fmt, arg); va_end(arg); try { - parser->on_fatal_error(Glib::ustring(buff)); - } - catch(const exception& e) - { - parser->handleException(e); + parser->on_fatal_error(buff); } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -637,20 +553,16 @@ void SaxParserCallback::cdata_block(void* context, const xmlChar* value, int len try { - // Here we force the use of Glib::ustring::ustring( InputIterator begin, InputIterator end ) + // Here we force the use of ustring::ustring( InputIterator begin, InputIterator end ) // see comments in SaxParserCallback::characters parser->on_cdata_block( - Glib::ustring( + ustring( reinterpret_cast(value), reinterpret_cast(value + len) ) ); } - catch(const exception& e) + catch (...) { - parser->handleException(e); - } - catch(...) - { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } @@ -659,21 +571,17 @@ void SaxParserCallback::internal_subset(void* context, const xmlChar* name, { auto the_context = static_cast<_xmlParserCtxt*>(context); auto parser = static_cast(the_context->_private); - + try { - const auto pid = publicId ? Glib::ustring((const char*) publicId) : ""; - const auto sid = systemId ? Glib::ustring((const char*) systemId) : ""; + const auto pid = publicId ? ustring((const char*) publicId) : ""; + const auto sid = systemId ? ustring((const char*) systemId) : ""; - parser->on_internal_subset( Glib::ustring((const char*) name), pid, sid); - } - catch(const exception& e) - { - parser->handleException(e); + parser->on_internal_subset( ustring((const char*) name), pid, sid); } - catch(...) + catch (...) { - parser->handleException(wrapped_exception(std::current_exception())); + parser->handle_exception(); } } diff --git a/libxml++/parsers/saxparser.h b/libxml++/parsers/saxparser.h index 6b3405a3..affacbf2 100644 --- a/libxml++/parsers/saxparser.h +++ b/libxml++/parsers/saxparser.h @@ -9,7 +9,6 @@ #include -#include #include #include #include "libxml++/document.h" @@ -25,6 +24,12 @@ namespace xmlpp { /** SAX XML parser. * Derive your own class and override the on_*() methods. + * SAX = Simple API for XML + * + * In a system that does not support std::exception_ptr: If an overridden on_*() + * method throws an exception which is not derived from xmlpp::exception, + * that exception is replaced by a xmlpp::exception before it is propagated + * out of the parse method, such as parse_file(). */ class SaxParser : public Parser { @@ -35,31 +40,31 @@ class SaxParser : public Parser */ struct Attribute { - Glib::ustring name; - Glib::ustring value; + ustring name; + ustring value; - Attribute(Glib::ustring const & n, Glib::ustring const & v) + Attribute(ustring const & n, ustring const & v) : name(n), value(v) { } }; - typedef std::deque< Attribute > AttributeList; + using AttributeList = std::deque; /** This functor is a helper to find an attribute by name in an * AttributeList using the standard algorithm std::find_if - * + * * Example:@n * - * Glib::ustring name = "foo";@n + * ustring name = "foo";@n * AttributeList::const_iterator attribute = std::find_if(attributes.begin(), attributes.end(), AttributeHasName(name)); * */ struct AttributeHasName { - Glib::ustring const & name; + ustring const & name; - AttributeHasName(Glib::ustring const & n) + AttributeHasName(ustring const & n) : name(n) { } @@ -69,15 +74,17 @@ class SaxParser : public Parser return attribute.name == name; } }; - - /** + + /** * @param use_get_entity Set this to true if you will override on_get_entity(). * In theory, if you do not override on_get_entity() the parser should behave exactly the same * whether you use true or false here. But the default implementation of on_get_entity(), needed * if you override on_get_entity() might not have the same behaviour as the underlying default * behaviour of libxml, so the libxml implementation is the default here. */ + LIBXMLPP_API SaxParser(bool use_get_entity = false); + LIBXMLPP_API ~SaxParser() override; /** Parse an XML document from a file. @@ -86,7 +93,8 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_file(const Glib::ustring& filename) override; + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse an XML document from a string. * @param contents The XML document as a string. @@ -94,7 +102,8 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_memory(const Glib::ustring& contents) override; + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse an XML document from raw memory. * @param contents The XML document as an array of bytes. @@ -103,7 +112,8 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - void parse_memory_raw(const unsigned char* contents, size_type bytes_count); + LIBXMLPP_API + void parse_memory_raw(const unsigned char* contents, size_type bytes_count) override; /** Parse an XML document from a stream. * @param in The stream. @@ -111,16 +121,16 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ + LIBXMLPP_API void parse_stream(std::istream& in) override; - - //TODO: Remove virtual when we can break ABI? + /** Parse a chunk of data. * * This lets you pass a document in small chunks, e.g. from a network * connection. The on_* virtual functions are called each time the chunks * provide enough information to advance the parser. * - * The first call to parse_chunk will setup the parser. When the last chunk + * The first call to parse_chunk() will setup the parser. When the last chunk * has been parsed, call finish_chunk_parsing() to finish the parse. * * @param chunk The next piece of the XML document. @@ -128,7 +138,8 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - virtual void parse_chunk(const Glib::ustring& chunk); + LIBXMLPP_API + void parse_chunk(const ustring& chunk); /** Parse a chunk of data. * @@ -138,7 +149,7 @@ class SaxParser : public Parser * connection. The on_* virtual functions are called each time the chunks * provide enough information to advance the parser. * - * The first call to parse_chunk will setup the parser. When the last chunk + * The first call to parse_chunk_raw() will setup the parser. When the last chunk * has been parsed, call finish_chunk_parsing() to finish the parse. * * @param contents The next piece of the XML document as an array of bytes. @@ -147,38 +158,50 @@ class SaxParser : public Parser * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ + LIBXMLPP_API void parse_chunk_raw(const unsigned char* contents, size_type bytes_count); - //TODO: Remove virtual when we can break ABI? /** Finish a chunk-wise parse. * - * Call this after the last call to parse_chunk(). Don't use this function with - * the other parsing methods. + * Call this after the last call to parse_chunk() or parse_chunk_raw(). + * Don't use this function with the other parsing methods. * @throws xmlpp::internal_error * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - virtual void finish_chunk_parsing(); + LIBXMLPP_API + void finish_chunk_parsing(); protected: - + + LIBXMLPP_API virtual void on_start_document(); + LIBXMLPP_API virtual void on_end_document(); - virtual void on_start_element(const Glib::ustring& name, const AttributeList& attributes); - virtual void on_end_element(const Glib::ustring& name); - virtual void on_characters(const Glib::ustring& characters); - virtual void on_comment(const Glib::ustring& text); - virtual void on_warning(const Glib::ustring& text); - virtual void on_error(const Glib::ustring& text); + LIBXMLPP_API + virtual void on_start_element(const ustring& name, const AttributeList& attributes); + LIBXMLPP_API + virtual void on_end_element(const ustring& name); + LIBXMLPP_API + virtual void on_characters(const ustring& characters); + LIBXMLPP_API + virtual void on_comment(const ustring& text); + LIBXMLPP_API + virtual void on_warning(const ustring& text); + LIBXMLPP_API + virtual void on_error(const ustring& text); /** @throws xmlpp::parse_error */ - virtual void on_fatal_error(const Glib::ustring& text); - virtual void on_cdata_block(const Glib::ustring& text); + LIBXMLPP_API + virtual void on_fatal_error(const ustring& text); + LIBXMLPP_API + virtual void on_cdata_block(const ustring& text); /** Override this to receive information about the document's DTD and any entity declarations. */ - virtual void on_internal_subset(const Glib::ustring& name, const Glib::ustring& publicId, const Glib::ustring& systemId); + LIBXMLPP_API + virtual void on_internal_subset(const ustring& name, const ustring& publicId, const ustring& systemId); /** Override this method to resolve entities references in your derived parser, instead of using the default entity resolution, * or to be informed when entity references are encountered. @@ -196,11 +219,12 @@ class SaxParser : public Parser * Unlike the DomParser, the SaxParser will also tell you about entity references for the 5 predefined entities. * * @param name The entity reference name. - * @returns The resolved xmlEntity for the entity reference, or 0 if not found. + * @returns The resolved xmlEntity for the entity reference, or nullptr if not found. * You must include libxml/parser.h in order to use this C struct. * This instance will not be freed by the caller. */ - virtual _xmlEntity* on_get_entity(const Glib::ustring& name); + LIBXMLPP_API + virtual _xmlEntity* on_get_entity(const ustring& name); /** Override this to receive information about every entity declaration. * If you override this function, and you want normal entity substitution to work, then you must call the base class in your override. @@ -208,19 +232,23 @@ class SaxParser : public Parser * This would be useful when overriding on_get_entity(). * @throws xmlpp::internal_error */ - virtual void on_entity_declaration(const Glib::ustring& name, XmlEntityType type, const Glib::ustring& publicId, const Glib::ustring& systemId, const Glib::ustring& content); + LIBXMLPP_API + virtual void on_entity_declaration(const ustring& name, XmlEntityType type, const ustring& publicId, const ustring& systemId, const ustring& content); + LIBXMLPP_API void release_underlying() override; - + LIBXMLPP_API + void initialize_context() override; + private: - //TODO: Remove the virtual when we can break ABI? - virtual void parse(); - - std::auto_ptr<_xmlSAXHandler> sax_handler_; + LIBXMLPP_API + void parse(); + + std::unique_ptr<_xmlSAXHandler> sax_handler_; // A separate xmlpp::Document that is just used for entity resolution, // and never seen in the API: - xmlpp::Document entity_resolver_doc_; + std::unique_ptr entity_resolver_doc_; friend struct SaxParserCallback; }; diff --git a/libxml++/parsers/textreader.cc b/libxml++/parsers/textreader.cc index 5eb04144..58c4863f 100644 --- a/libxml++/parsers/textreader.cc +++ b/libxml++/parsers/textreader.cc @@ -5,22 +5,65 @@ #include #include +#include + +namespace +{ +//TODO: When we can break ABI, change on_libxml_error(), and change ErrorFuncType to +// using ErrorFuncType = void (*)(void* userData, const xmlError* error); +// C++ linkage +using ErrorFuncType = void (*)(void* arg, const char* msg, int severity, void* locator); +ErrorFuncType p_callback_error; + +extern "C" +{ +#if LIBXML_VERSION >= 21200 +static void c_callback_error(void* userData, const xmlError* error) +#else +static void c_callback_error(void* userData, xmlError* error) +#endif +{ + const xmlpp::ustring msg = xmlpp::format_xml_error(error); + + // Compute severity as in libxml2's xmlreader.c file, + // static (i.e. private) function xmlTextReaderStructuredRelay(). + xmlParserSeverities severity{}; + switch (error->domain) + { + case XML_FROM_VALID: + case XML_FROM_DTD: + severity = (error->level == XML_ERR_WARNING) ? + XML_PARSER_SEVERITY_VALIDITY_WARNING : + XML_PARSER_SEVERITY_VALIDITY_ERROR; + break; + default: + severity = (error->level == XML_ERR_WARNING) ? + XML_PARSER_SEVERITY_WARNING : + XML_PARSER_SEVERITY_ERROR; + break; + } + p_callback_error(userData, msg.c_str(), severity, nullptr); +} + +} // extern "C" +} // anonymous namespace namespace xmlpp { - + class TextReader::PropertyReader { public: - PropertyReader(TextReader& owner) + explicit PropertyReader(TextReader& owner) : owner_(owner) {} int Int(int value); bool Bool(int value); char Char(int value); - Glib::ustring String(xmlChar* value, bool free = false); - Glib::ustring String(xmlChar const* value); + ustring String(xmlChar* value, bool free = false); + ustring String(xmlChar const* value); + std::optional OptString(xmlChar* value); TextReader & owner_; }; @@ -34,11 +77,11 @@ TextReader::TextReader( } TextReader::TextReader( - const unsigned char* data, + const unsigned char* data, size_type size, - const Glib::ustring& uri) - : propertyreader(new PropertyReader(*this)), - impl_( xmlReaderForMemory ((const char*)data, size, uri.c_str(), 0, 0) ), + const ustring& uri) + : propertyreader(new PropertyReader(*this)), + impl_( xmlReaderForMemory ((const char*)data, size, uri.c_str(), nullptr, 0) ), severity_( 0 ) { if( ! impl_ ) @@ -50,7 +93,7 @@ TextReader::TextReader( } TextReader::TextReader( - const Glib::ustring& URI) + const ustring& URI) : propertyreader(new PropertyReader(*this)), impl_( xmlNewTextReaderFilename(URI.c_str()) ), severity_( 0 ) { @@ -73,23 +116,40 @@ bool TextReader::read() xmlTextReaderRead(impl_)); } -Glib::ustring TextReader::read_inner_xml() +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::read_inner_xml() { return propertyreader->String( xmlTextReaderReadInnerXml(impl_), true); } -Glib::ustring TextReader::read_outer_xml() +ustring TextReader::read_outer_xml() { return propertyreader->String( xmlTextReaderReadOuterXml(impl_), true); } -Glib::ustring TextReader::read_string() +ustring TextReader::read_string() { return propertyreader->String( xmlTextReaderReadString(impl_), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional TextReader::read_inner_xml2() +{ + return propertyreader->OptString(xmlTextReaderReadInnerXml(impl_)); +} + +std::optional TextReader::read_outer_xml2() +{ + return propertyreader->OptString(xmlTextReaderReadOuterXml(impl_)); +} + +std::optional TextReader::read_string2() +{ + return propertyreader->OptString(xmlTextReaderReadString(impl_)); +} bool TextReader::read_attribute_value() { @@ -103,11 +163,18 @@ int TextReader::get_attribute_count() const xmlTextReaderAttributeCount(impl_)); } -Glib::ustring TextReader::get_base_uri() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::get_base_uri() const { return propertyreader->String( xmlTextReaderBaseUri(impl_), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional TextReader::get_base_uri2() const +{ + return propertyreader->OptString(xmlTextReaderBaseUri(impl_)); +} int TextReader::get_depth() const { @@ -139,37 +206,61 @@ bool TextReader::is_empty_element() const xmlTextReaderIsEmptyElement(impl_)); } -Glib::ustring TextReader::get_local_name() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::get_local_name() const { return propertyreader->String( xmlTextReaderLocalName(impl_), true); } -Glib::ustring TextReader::get_name() const +ustring TextReader::get_name() const { return propertyreader->String( xmlTextReaderName(impl_), true); } -Glib::ustring TextReader::get_namespace_uri() const +ustring TextReader::get_namespace_uri() const { return propertyreader->String( xmlTextReaderNamespaceUri(impl_), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED -TextReader::xmlNodeType TextReader::get_node_type() const +std::optional TextReader::get_local_name2() const +{ + return propertyreader->OptString(xmlTextReaderLocalName(impl_)); +} + +std::optional TextReader::get_name2() const +{ + return propertyreader->OptString(xmlTextReaderName(impl_)); +} + +std::optional TextReader::get_namespace_uri2() const +{ + return propertyreader->OptString(xmlTextReaderNamespaceUri(impl_)); +} + +TextReader::NodeType TextReader::get_node_type() const { int result = xmlTextReaderNodeType(impl_); if(result == -1) check_for_exceptions(); - return (xmlNodeType)result; + return static_cast(result); } -Glib::ustring TextReader::get_prefix() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::get_prefix() const { return propertyreader->String( xmlTextReaderPrefix(impl_), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional TextReader::get_prefix2() const +{ + return propertyreader->OptString(xmlTextReaderPrefix(impl_)); +} char TextReader::get_quote_char() const { @@ -177,24 +268,36 @@ char TextReader::get_quote_char() const xmlTextReaderQuoteChar(impl_)); } -Glib::ustring TextReader::get_value() const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::get_value() const { return propertyreader->String( xmlTextReaderValue(impl_), true); } -Glib::ustring TextReader::get_xml_lang() const +ustring TextReader::get_xml_lang() const { return propertyreader->String( - xmlTextReaderXmlLang(impl_)); + xmlTextReaderXmlLang(impl_), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED -TextReader::xmlReadState TextReader::get_read_state() const +std::optional TextReader::get_value2() const +{ + return propertyreader->OptString(xmlTextReaderValue(impl_)); +} + +std::optional TextReader::get_xml_lang2() const +{ + return propertyreader->OptString(xmlTextReaderXmlLang(impl_)); +} + +TextReader::ReadState TextReader::get_read_state() const { int result = xmlTextReaderReadState(impl_); if(result == -1) check_for_exceptions(); - return (xmlReadState)result; + return static_cast(result); } void TextReader::close() @@ -203,33 +306,62 @@ void TextReader::close() check_for_exceptions(); } -Glib::ustring TextReader::get_attribute(int number) const +#ifndef LIBXMLXX_DISABLE_DEPRECATED +ustring TextReader::get_attribute(int number) const { return propertyreader->String( xmlTextReaderGetAttributeNo(impl_, number), true); } -Glib::ustring TextReader::get_attribute( - const Glib::ustring& name) const +ustring TextReader::get_attribute( + const ustring& name) const { return propertyreader->String( xmlTextReaderGetAttribute(impl_, (const xmlChar *)name.c_str()), true); } -Glib::ustring TextReader::get_attribute( - const Glib::ustring& localName, - const Glib::ustring& namespaceURI) const +ustring TextReader::get_attribute( + const ustring& localName, + const ustring& namespaceURI) const { return propertyreader->String( - xmlTextReaderGetAttributeNs(impl_, (const xmlChar *)localName.c_str(), (const xmlChar *)namespaceURI.c_str()), true); + xmlTextReaderGetAttributeNs(impl_, (const xmlChar *)localName.c_str(), + (const xmlChar *)namespaceURI.c_str()), true); } -Glib::ustring TextReader::lookup_namespace( - const Glib::ustring& prefix) const +ustring TextReader::lookup_namespace( + const ustring& prefix) const { return propertyreader->String( xmlTextReaderLookupNamespace(impl_, (const xmlChar *)prefix.c_str()), true); } +#endif // LIBXMLXX_DISABLE_DEPRECATED + +std::optional TextReader::get_attribute2(int number) const +{ + return propertyreader->OptString(xmlTextReaderGetAttributeNo(impl_, number)); +} + +std::optional TextReader::get_attribute2(const ustring& name) const +{ + return propertyreader->OptString( + xmlTextReaderGetAttribute(impl_, (const xmlChar*)name.c_str())); +} + +std::optional TextReader::get_attribute2( + const ustring& localName, + const ustring& namespaceURI) const +{ + return propertyreader->OptString( + xmlTextReaderGetAttributeNs(impl_, (const xmlChar*)localName.c_str(), + (const xmlChar *)namespaceURI.c_str())); +} + +std::optional TextReader::lookup_namespace2(const ustring& prefix) const +{ + return propertyreader->OptString(xmlTextReaderLookupNamespace( + impl_, prefix.empty() ? nullptr : (const xmlChar*)prefix.c_str())); +} bool TextReader::move_to_attribute(int number) { @@ -238,15 +370,15 @@ bool TextReader::move_to_attribute(int number) } bool TextReader::move_to_attribute( - const Glib::ustring& name) + const ustring& name) { return propertyreader->Bool( xmlTextReaderMoveToAttribute(impl_, (const xmlChar *)name.c_str())); } bool TextReader::move_to_attribute( - const Glib::ustring& localName, - const Glib::ustring& namespaceURI) + const ustring& localName, + const ustring& namespaceURI) { return propertyreader->Bool( xmlTextReaderMoveToAttributeNs(impl_, (const xmlChar *)localName.c_str(), (const xmlChar *)namespaceURI.c_str())); @@ -299,9 +431,9 @@ Node* TextReader::get_current_node() Node::create_wrapper(node); return static_cast(node->_private); } - + check_for_exceptions(); - return 0; + return nullptr; } const Node* TextReader::get_current_node() const @@ -327,9 +459,9 @@ Node* TextReader::expand() Node::create_wrapper(node); return static_cast(node->_private); } - + check_for_exceptions(); - return 0; + return nullptr; } bool TextReader::next() @@ -346,21 +478,17 @@ bool TextReader::is_valid() const void TextReader::setup_exceptions() { - xmlTextReaderErrorFunc func = nullptr; - void* arg = nullptr; - - // We respect any other error handlers already setup: - xmlTextReaderGetErrorHandler(impl_, &func, &arg); - if(!func) - { - func = (xmlTextReaderErrorFunc)&TextReader::on_libxml_error; - xmlTextReaderSetErrorHandler(impl_, func, this); - } + p_callback_error = &on_libxml_error; + xmlTextReaderSetStructuredErrorHandler(impl_, &c_callback_error, this); } void TextReader::on_libxml_error(void* arg, const char* msg, int severity, void* /* locator */) { - auto ths = (TextReader*)arg; + //TODO: Change this function when we can break ABI. + // It was created when setup_exceptions() called xmlTextReaderSetErrorHandler() + // instead of xmlTextReaderSetStructuredErrorHandler(). + + auto ths = static_cast(arg); ths->severity_ = severity; ths->error_ = msg ? msg : "unknown parse error"; } @@ -369,7 +497,7 @@ void TextReader::check_for_exceptions() const { if( severity_ == 0 ) return; - + auto ths = const_cast(this); int severity = severity_; @@ -393,7 +521,7 @@ bool TextReader::PropertyReader::Bool(int value) { if(value == -1) owner_.check_for_exceptions(); - + return value > 0; } @@ -403,14 +531,14 @@ char TextReader::PropertyReader::Char(int value) return value; } -Glib::ustring TextReader::PropertyReader::String(xmlChar* value, bool free) +ustring TextReader::PropertyReader::String(xmlChar* value, bool free) { owner_.check_for_exceptions(); - - if(value == (xmlChar *)0) - return Glib::ustring(); - - const Glib::ustring result = (char *)value; + + if (!value) + return ustring(); + + ustring result = (char *)value; if(free) xmlFree(value); @@ -418,14 +546,26 @@ Glib::ustring TextReader::PropertyReader::String(xmlChar* value, bool free) return result; } -Glib::ustring TextReader::PropertyReader::String(xmlChar const* value) +ustring TextReader::PropertyReader::String(xmlChar const* value) { owner_.check_for_exceptions(); - if(value == (xmlChar *)0) - return Glib::ustring(); + if (!value) + return ustring(); return (const char*)value; } +std::optional TextReader::PropertyReader::OptString(xmlChar* value) +{ + owner_.check_for_exceptions(); + + if (!value) + return {}; + + std::optional result = (char*)value; + xmlFree(value); + return result; +} + } // namespace xmlpp diff --git a/libxml++/parsers/textreader.h b/libxml++/parsers/textreader.h index 5901894d..caa3da64 100644 --- a/libxml++/parsers/textreader.h +++ b/libxml++/parsers/textreader.h @@ -10,15 +10,18 @@ #include #include -#include +#include "libxml++/ustring.h" #include +#include extern "C" { struct _xmlTextReader; } +//TODO: When we can break ABI/API, remove deprecated methods +// and rename all xyz2() to xyz(). namespace xmlpp { @@ -26,41 +29,50 @@ namespace xmlpp * A reader that provides fast, non-cached, forward-only access to XML data, * in the style of .Net's XmlTextReader class. */ -class TextReader: NonCopyable +class TextReader: public NonCopyable { public: - enum xmlNodeType { + // xmlpp::TextReader::NodeType is similar to xmlReaderTypes in libxml2. + /** Node type of the current node. + * See DotGNU's XmlNodeType enum. + */ + enum class NodeType + { + InternalError = -1, + None = 0, + Element = 1, Attribute = 2, + Text = 3, CDATA = 4, + EntityReference = 5, + Entity = 6, + ProcessingInstruction = 7, Comment = 8, Document = 9, - DocumentFragment = 11, DocumentType = 10, - Element = 1, - EndElement = 15, - EndEntity = 16, - Entity = 6, - EntityReference = 5, - None = 0, + DocumentFragment = 11, Notation = 12, - ProcessingInstruction = 7, - SignificantWhitespace = 14, - Text = 3, Whitespace = 13, + SignificantWhitespace = 14, + EndElement = 15, + EndEntity = 16, XmlDeclaration = 17 }; - enum xmlReadState + // xmlpp::TextReader::ReadState is similar to xmlTextReaderMode in libxml2. + enum class ReadState { - Closed = 4, - EndOfFile = 3, - Error = 2, + InternalError = -1, Initial = 0, Interactive = 1, + Error = 2, + EndOfFile = 3, + Closed = 4, Reading = 5 }; - enum ParserProperties + // xmlpp::TextReader::ParserProperties is similar to xmlParserProperties in libxml2. + enum class ParserProperties { LoadDtd = 1, DefaultAttrs = 2, @@ -68,7 +80,7 @@ class TextReader: NonCopyable SubstEntities = 4 }; - typedef unsigned int size_type; + using size_type = unsigned int; public: /** @@ -76,6 +88,7 @@ class TextReader: NonCopyable * takes ownership of cobj. * @param cobj The underlying libxml xmlTextReader object. */ + LIBXMLPP_API TextReader(struct _xmlTextReader* cobj); /** @@ -83,7 +96,8 @@ class TextReader: NonCopyable * @param URI The URI to read. * @throws xmlpp::internal_error If an xmlTextReader object cannot be created. */ - TextReader(const Glib::ustring& URI); + LIBXMLPP_API + TextReader(const ustring& URI); /** * Creates a new TextReader object which parses in memory data. @@ -92,43 +106,77 @@ class TextReader: NonCopyable * @param uri The base URI to use for the document. * @throws xmlpp::internal_error If an xmlTextReader object cannot be created. */ - TextReader(const unsigned char* data, size_type size, const Glib::ustring& uri = Glib::ustring()); + LIBXMLPP_API + TextReader(const unsigned char* data, size_type size, const ustring& uri = ustring()); - ~TextReader(); + LIBXMLPP_API ~TextReader() override; /** Moves the position of the current instance to the next node in the stream, exposing its properties. * @return true if the node was read successfully, false if there are no more nodes to read. * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - bool read(); + LIBXMLPP_API bool read(); + +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Reads the contents of the current node, including child nodes and markup. + * @return A ustring containing the XML content, or an empty ustring if the current node is neither an element nor attribute, or has no child nodes. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use read_inner_xml2() instead. + */ + LIBXMLPP_API ustring read_inner_xml(); + + /** Reads the current node and its contents, including child nodes and markup. + * @return A ustring containing the XML content, or an empty ustring if the current node is neither an element nor attribute. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use read_outer_xml2() instead. + */ + LIBXMLPP_API ustring read_outer_xml(); + + /** Reads the contents of an element or a text node as a string. + * @return A ustring containing the contents of the Element or Text node, or an empty ustring if the reader is positioned on any other type of node. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use read_string2() instead. + */ + LIBXMLPP_API ustring read_string(); +#endif // LIBXMLXX_DISABLE_DEPRECATED /** Reads the contents of the current node, including child nodes and markup. - * @return A Glib::ustring containing the XML content, or an empty Glib::ustring if the current node is neither an element nor attribute, or has no child nodes. + * @return A std::optional containing the XML content, or no value if + * the current node is neither an element nor attribute, or has no child nodes. * @throws xmlpp::parse_error * @throws xmlpp::validity_error + * @newin{5,6} */ - Glib::ustring read_inner_xml(); + LIBXMLPP_API std::optional read_inner_xml2(); /** Reads the current node and its contents, including child nodes and markup. - * @return A Glib::ustring containing the XML content, or an empty Glib::ustring if the current node is neither an element nor attribute. + * @return A std::optional containing the XML content, or no value if + * the current node is neither an element nor attribute. * @throws xmlpp::parse_error * @throws xmlpp::validity_error + * @newin{5,6} */ - Glib::ustring read_outer_xml(); + LIBXMLPP_API std::optional read_outer_xml2(); /** Reads the contents of an element or a text node as a string. - * @return A Glib::ustring containing the contents of the Element or Text node, or an empty Glib::ustring if the reader is positioned on any other type of node. + * @return A std::optional containing the contents of the Element or Text node, + * or no value if the reader is positioned on any other type of node. * @throws xmlpp::parse_error * @throws xmlpp::validity_error + * @newin{5,6} */ - Glib::ustring read_string(); + LIBXMLPP_API std::optional read_string2(); /** Parses an attribute value into one or more Text and EntityReference nodes. * @return A bool where true indicates the attribute value was parsed, and false indicates the reader was not positioned on an attribute node or all the attribute values have been read. * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ + LIBXMLPP_API bool read_attribute_value(); /** Gets the number of attributes on the current node. @@ -137,83 +185,280 @@ class TextReader: NonCopyable * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ + LIBXMLPP_API int get_attribute_count() const; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Gets the base Uniform Resource Identifier (URI) of the current node. - * @return The base URI of the current node or an empty Glib::ustring if not available. + * @return The base URI of the current node or an empty ustring if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_base_uri2() instead. */ - Glib::ustring get_base_uri() const; + LIBXMLPP_API ustring get_base_uri() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Gets the base Uniform Resource Identifier (URI) of the current node. + * @return The base URI of the current node, or no value if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_base_uri2() const; /** Gets the depth of the current node in the XML document. * @return The depth of the current node in the XML document, or -1 in case of error. */ + LIBXMLPP_API int get_depth() const; /** Gets a value indicating whether the current node has any attributes. * @return true if the current has attributes, false otherwise. */ + LIBXMLPP_API bool has_attributes() const; /** Whether the node can have a text value. * @return true if the current node can have an associated text value, false otherwise. */ + LIBXMLPP_API bool has_value() const; /** Whether an Attribute node was generated from the default value defined in the DTD or schema. * @return true if defaulted, false otherwise. */ + LIBXMLPP_API bool is_default() const; /** Check if the current node is empty * @return true if empty, false otherwise. */ + LIBXMLPP_API bool is_empty_element() const; - Glib::ustring get_local_name() const; - Glib::ustring get_name() const; - Glib::ustring get_namespace_uri() const; +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Gets the local name of the node. + * @return The local name of the node, or an empty ustring if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_local_name2() instead. + */ + LIBXMLPP_API ustring get_local_name() const; + + /** Gets the qualified name of the node, equal to Prefix:LocalName. + * @return The qualified name of the node, or an empty ustring if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_name2() instead. + */ + LIBXMLPP_API ustring get_name() const; + + /** Gets the URI defining the namespace associated with the node. + * @return The namespace URI, or an empty ustring if not available. + * @deprecated 5.6: Use get_namespace_uri2() instead. + */ + LIBXMLPP_API ustring get_namespace_uri() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Gets the local name of the node. + * @return The local name of the node, or no value if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_local_name2() const; + + /** Gets the qualified name of the node, equal to Prefix:LocalName. + * @return The qualified name of the node, or no value if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_name2() const; + + /** Gets the URI defining the namespace associated with the node. + * @return The namespace URI, or no value if not available. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_namespace_uri2() const; /** Get the node type of the current node. - * @returns The xmlpp::xmlNodeType of the current node, or -1 in case of error. + * @returns The xmlpp::TextReader::NodeType of the current node. + * In case of error, either returns xmlpp::TextReader::NodeType::InternalError + * or throws an exception. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error */ - xmlNodeType get_node_type() const; + LIBXMLPP_API + NodeType get_node_type() const; +#ifndef LIBXMLXX_DISABLE_DEPRECATED /** Get the namespace prefix associated with the current node. * @returns The namespace prefix, or an empty string if not available. + * @deprecated 5.6: Use get_prefix2() instead. */ - Glib::ustring get_prefix() const; + LIBXMLPP_API ustring get_prefix() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Get the namespace prefix associated with the current node. + * @returns The namespace prefix, or no value if not available. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_prefix2() const; /** Get the quotation mark character used to enclose the value of an attribute. * @returns Returns " or ' and -1 in case of error. */ + LIBXMLPP_API char get_quote_char() const; - Glib::ustring get_value() const; - Glib::ustring get_xml_lang() const; +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Gets the text value of the node. + * @return The text value, or an empty ustring if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_value2() instead. + */ + LIBXMLPP_API ustring get_value() const; + + /** Gets the xml:lang scope within which the node resides. + * @return The xml:lang value, or an empty ustring if not available. + * @deprecated 5.6: Use get_xml_lang2() instead. + */ + LIBXMLPP_API ustring get_xml_lang() const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Gets the text value of the node. + * @return The text value, or no value if not available. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_value2() const; + + /** Gets the xml:lang scope within which the node resides. + * @return The xml:lang value, or no value if not available. + * @newin{5,6} + */ + LIBXMLPP_API std::optional get_xml_lang2() const; + + /** Gets the read state of the reader. + * @return The state value, or xmlpp::TextReader::ReadState::InternalError in case of error. + */ + LIBXMLPP_API + ReadState get_read_state() const; + + LIBXMLPP_API void close(); - xmlReadState get_read_state() const; +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** Gets the value of the attribute with the specified index relative to the containing element. + * @param number The zero-based index of the attribute relative to the containing element. + * @return The value of the specified attribute, or an empty ustring in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_attribute2(int) const instead. + */ + LIBXMLPP_API + ustring get_attribute(int number) const; - void close(); + /** Gets the value of the attribute with the specified qualified name. + * @param name The qualified name of the attribute. + * @return The value of the specified attribute, or an empty ustring in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_attribute2(const ustring&) const instead. + */ + LIBXMLPP_API + ustring get_attribute(const ustring& name) const; - Glib::ustring get_attribute(int number) const; - Glib::ustring get_attribute(const Glib::ustring& name) const; - Glib::ustring get_attribute(const Glib::ustring& local_name, const Glib::ustring& ns_uri) const; + /** Gets the value of the specified attribute. + * @param local_name The local name of the attribute. + * @param ns_uri The namespace URI of the attribute. + * @return The value of the specified attribute, or an empty ustring in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use get_attribute2(const ustring&, const ustring&) const instead. + */ + LIBXMLPP_API + ustring get_attribute(const ustring& local_name, const ustring& ns_uri) const; + + /** Resolves a namespace prefix in the scope of the current element. + * @param prefix The prefix whose namespace URI is to be resolved. + * To return the default namespace, specify an empty string. + * @return The the namespace URI to which the prefix maps, or an empty ustring in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @deprecated 5.6: Use lookup_namespace2() instead. + */ + LIBXMLPP_API + ustring lookup_namespace(const ustring& prefix) const; +#endif // LIBXMLXX_DISABLE_DEPRECATED + + /** Gets the value of the attribute with the specified index relative to the containing element. + * @param number The zero-based index of the attribute relative to the containing element. + * @return The value of the specified attribute, or no value in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API + std::optional get_attribute2(int number) const; + + /** Gets the value of the attribute with the specified qualified name. + * @param name The qualified name of the attribute. + * @return The value of the specified attribute, or no value in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API + std::optional get_attribute2(const ustring& name) const; + + /** Gets the value of the specified attribute. + * @param local_name The local name of the attribute. + * @param ns_uri The namespace URI of the attribute. + * @return The value of the specified attribute, or no value in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API + std::optional get_attribute2(const ustring& local_name, const ustring& ns_uri) const; // TODO InputBuffer GetRemainder; - Glib::ustring lookup_namespace(const Glib::ustring& prefix) const; + /** Resolves a namespace prefix in the scope of the current element. + * @param prefix The prefix whose namespace URI is to be resolved. + * To return the default namespace, specify an empty string. + * @return The the namespace URI to which the prefix maps, or no value in case of error. + * @throws xmlpp::parse_error + * @throws xmlpp::validity_error + * @newin{5,6} + */ + LIBXMLPP_API + std::optional lookup_namespace2(const ustring& prefix) const; + LIBXMLPP_API bool move_to_attribute(int number); - bool move_to_attribute(const Glib::ustring& name); - bool move_to_attribute(const Glib::ustring& local_name, const Glib::ustring& ns_uri); + LIBXMLPP_API + bool move_to_attribute(const ustring& name); + LIBXMLPP_API + bool move_to_attribute(const ustring& local_name, const ustring& ns_uri); + LIBXMLPP_API bool move_to_first_attribute(); + LIBXMLPP_API bool move_to_next_attribute(); + LIBXMLPP_API bool move_to_element(); + LIBXMLPP_API bool get_normalization() const; + LIBXMLPP_API void set_normalization(bool value); + LIBXMLPP_API bool get_parser_property(ParserProperties property) const; + LIBXMLPP_API void set_parser_property(ParserProperties property, bool value); /** Get a pointer to the current node. @@ -221,14 +466,16 @@ class TextReader: NonCopyable * The C++ wrapper is not deleted. Using this method causes memory leaks, * unless you call xmlpp::Node::free_wrappers(), which is not intended to be * called by the application. - * @returns A pointer to the current node, or 0 in case of error. + * @returns A pointer to the current node, or nullptr in case of error. */ + LIBXMLPP_API Node* get_current_node(); /** Get a pointer to the current node. * @warning See the non-const get_current_node(). - * @returns A pointer to the current node, or 0 in case of error. + * @returns A pointer to the current node, or nullptr in case of error. */ + LIBXMLPP_API const Node* get_current_node() const; // Document* CurrentDocument(); @@ -239,28 +486,33 @@ class TextReader: NonCopyable * @warning The C++ wrappers are not deleted. Using this method causes memory leaks, * unless you call xmlpp::Node::free_wrappers(), which is not intended to be * called by the application. - * @returns A pointer to the current node, or 0 in case of error. + * @returns A pointer to the current node, or nullptr in case of error. * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - Node* expand(); + LIBXMLPP_API Node* expand(); - bool next(); - bool is_valid() const; + LIBXMLPP_API bool next(); + LIBXMLPP_API bool is_valid() const; private: class PropertyReader; friend class PropertyReader; + LIBXMLPP_API void setup_exceptions(); + //TODO: When we can break ABI, change on_libxml_error() to + // static void on_libxml_error(void* userData, const xmlError* error); + LIBXMLPP_API static void on_libxml_error(void * arg, const char *msg, int severity, void * locator); + LIBXMLPP_API void check_for_exceptions() const; - std::auto_ptr propertyreader; + std::unique_ptr propertyreader; _xmlTextReader* impl_; int severity_; - Glib::ustring error_; + ustring error_; }; } diff --git a/libxml++/relaxngschema.cc b/libxml++/relaxngschema.cc index 96bd8807..20f20efe 100644 --- a/libxml++/relaxngschema.cc +++ b/libxml++/relaxngschema.cc @@ -31,7 +31,7 @@ namespace class RelaxNGSchemaParserContextHolder { public: - RelaxNGSchemaParserContextHolder(xmlRelaxNGParserCtxtPtr ctx): ctx_(ctx) {} + explicit RelaxNGSchemaParserContextHolder(xmlRelaxNGParserCtxtPtr ctx) noexcept : ctx_(ctx) {} ~RelaxNGSchemaParserContextHolder() { if (ctx_) xmlRelaxNGFreeParserCtxt(ctx_); } private: @@ -44,12 +44,12 @@ namespace xmlpp struct RelaxNGSchema::Impl { - Impl() : schema(nullptr) {} + Impl() noexcept : schema(nullptr) {} _xmlRelaxNG* schema; }; - + RelaxNGSchema::RelaxNGSchema() : pimpl_(new Impl) { @@ -61,7 +61,7 @@ RelaxNGSchema::RelaxNGSchema(_xmlRelaxNG* schema) pimpl_->schema = schema; } -RelaxNGSchema::RelaxNGSchema(const Glib::ustring& filename) +RelaxNGSchema::RelaxNGSchema(const std::string& filename) : pimpl_(new Impl) { parse_file(filename); @@ -78,20 +78,20 @@ RelaxNGSchema::~RelaxNGSchema() release_underlying(); } -void RelaxNGSchema::parse_file(const Glib::ustring& filename) +void RelaxNGSchema::parse_file(const std::string& filename) { parse_context(xmlRelaxNGNewParserCtxt(filename.c_str())); } -void RelaxNGSchema::parse_memory(const Glib::ustring& contents) +void RelaxNGSchema::parse_memory(const ustring& contents) { - parse_context(xmlRelaxNGNewMemParserCtxt(contents.c_str(), contents.bytes())); + parse_context(xmlRelaxNGNewMemParserCtxt(contents.c_str(), contents.size())); } void RelaxNGSchema::parse_document(const Document* document) { if (!document) - throw parse_error("RelaxNGSchema::parse_document(): document must not be 0."); + throw parse_error("RelaxNGSchema::parse_document(): document must not be nullptr."); // xmlRelaxNGNewDocParserCtxt() takes a copy of the xmlDoc. parse_context(xmlRelaxNGNewDocParserCtxt(const_cast(document->cobj()))); @@ -104,7 +104,7 @@ void RelaxNGSchema::parse_context(_xmlRelaxNGParserCtxt* context) if (!context) throw parse_error("RelaxNGSchema::parse_context(): Could not create parser context.\n" + format_xml_error()); - + RelaxNGSchemaParserContextHolder holder(context); pimpl_->schema = xmlRelaxNGParse(context); @@ -112,12 +112,12 @@ void RelaxNGSchema::parse_context(_xmlRelaxNGParserCtxt* context) throw parse_error("RelaxNGSchema::parse_context(): Schema could not be parsed.\n" + format_xml_error()); } -_xmlRelaxNG* RelaxNGSchema::cobj() +_xmlRelaxNG* RelaxNGSchema::cobj() noexcept { return pimpl_->schema; } -const _xmlRelaxNG* RelaxNGSchema::cobj() const +const _xmlRelaxNG* RelaxNGSchema::cobj() const noexcept { return pimpl_->schema; } diff --git a/libxml++/relaxngschema.h b/libxml++/relaxngschema.h index 8df7089b..ffa00792 100644 --- a/libxml++/relaxngschema.h +++ b/libxml++/relaxngschema.h @@ -23,7 +23,7 @@ #include #include -#include // std::auto_ptr +#include // std::unique_ptr #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { @@ -43,12 +43,13 @@ namespace xmlpp class RelaxNGSchema : public SchemaBase { public: - RelaxNGSchema(); + LIBXMLPP_API RelaxNGSchema(); /** Create a schema from the underlying libxml schema element. * @param schema A pointer to the libxml schema element. The RelaxNGSchema takes * ownership of the _xmlRelaxNG. The caller must not deallocate it. */ + LIBXMLPP_API explicit RelaxNGSchema(_xmlRelaxNG* schema); /** Create a schema from a schema definition file. @@ -57,15 +58,17 @@ class RelaxNGSchema : public SchemaBase * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - explicit RelaxNGSchema(const Glib::ustring& filename); + LIBXMLPP_API + explicit RelaxNGSchema(const std::string& filename); /** Create a schema from an XML document. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API explicit RelaxNGSchema(const Document* document); - ~RelaxNGSchema() override; + LIBXMLPP_API ~RelaxNGSchema() override; /** Parse a schema definition file. * The schema must be defined with XML syntax (.rng file). The compact syntax @@ -75,7 +78,8 @@ class RelaxNGSchema : public SchemaBase * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - void parse_file(const Glib::ustring& filename) override; + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse a schema definition from a string. * The schema must be defined with XML syntax. The compact syntax is not supported. @@ -84,28 +88,34 @@ class RelaxNGSchema : public SchemaBase * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - void parse_memory(const Glib::ustring& contents) override; + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse a schema definition from a document. * If another schema has been parsed before, that schema is replaced by the new one. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API void parse_document(const Document* document) override; /** Access the underlying libxml implementation. */ - _xmlRelaxNG* cobj(); + LIBXMLPP_API + _xmlRelaxNG* cobj() noexcept; /** Access the underlying libxml implementation. */ - const _xmlRelaxNG* cobj() const; + LIBXMLPP_API + const _xmlRelaxNG* cobj() const noexcept; protected: + LIBXMLPP_API void release_underlying(); + LIBXMLPP_API void parse_context(_xmlRelaxNGParserCtxt* context); private: struct Impl; - std::auto_ptr pimpl_; + std::unique_ptr pimpl_; }; } // namespace xmlpp diff --git a/libxml++/schema.cc b/libxml++/schema.cc deleted file mode 100644 index 1b39b24b..00000000 --- a/libxml++/schema.cc +++ /dev/null @@ -1,131 +0,0 @@ -/* schema.cc - * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and - * are covered by the GNU Lesser General Public License, which should be - * included with libxml++ as the file COPYING. - */ - -#include // LIBXMLXX_DISABLE_DEPRECATED - -#ifndef LIBXMLXX_DISABLE_DEPRECATED - -#include - -#include -#include -#include - -namespace xmlpp -{ - -Schema::Schema(_xmlSchema* schema) -: impl_(schema) -, embedded_doc_(false) -{ - schema->_private = this; -} - -Schema::Schema(Document* document, bool embed) -: impl_(nullptr) -, embedded_doc_(false) -{ - set_document(document, embed); -} - -Schema::~Schema() -{ - release_underlying(); -} - -void Schema::set_document(Document* document, bool embed) -{ - release_underlying(); - - bool has_created_document = false; - if (!document) - { - document = new Document(); - has_created_document = true; - } - - xmlResetLastError(); - auto context = xmlSchemaNewDocParserCtxt( document->cobj() ); - - if(!context) - { - if (has_created_document) - delete document; - throw parse_error("Schema could not be parsed.\n" + format_xml_error()); - } - - impl_ = xmlSchemaParse(context); - if(!impl_) - { - xmlSchemaFreeParserCtxt(context); - if (has_created_document) - delete document; - throw parse_error("Schema could not be parsed.\n" + format_xml_error()); - } - - impl_->_private = this; - embedded_doc_ = embed; - xmlSchemaFreeParserCtxt(context); -} - -Glib::ustring Schema::get_name() const -{ - return (impl_ && impl_->name) ? (char*)impl_->name : ""; -} - -Glib::ustring Schema::get_target_namespace() const -{ - return (impl_ && impl_->targetNamespace) ? (char*)impl_->targetNamespace : ""; -} - -Glib::ustring Schema::get_version() const -{ - return (impl_ && impl_->version) ? (char*)impl_->version : ""; -} - -void Schema::release_underlying() -{ - if(embedded_doc_ && impl_ && impl_->doc && impl_->doc->_private) - { - delete (Document*) impl_->doc->_private; - embedded_doc_ = false; - } - - if(impl_) - { - xmlSchemaFree(impl_); - impl_ = nullptr; - } -} - -Document* Schema::get_document() -{ - if (!(impl_ && impl_->doc)) - return 0; - - if (!impl_->doc->_private) // Possible if *this was created with Schema(xmlSchema* schema). - new Document(impl_->doc); // Sets impl_->doc->_private - - return (Document*) impl_->doc->_private; -} - -const Document* Schema::get_document() const -{ - return const_cast(this)->get_document(); -} - -_xmlSchema* Schema::cobj() -{ - return impl_; -} - -const _xmlSchema* Schema::cobj() const -{ - return impl_; -} - -} //namespace xmlpp -#endif // LIBXMLXX_DISABLE_DEPRECATED diff --git a/libxml++/schema.h b/libxml++/schema.h deleted file mode 100644 index 69299c86..00000000 --- a/libxml++/schema.h +++ /dev/null @@ -1,111 +0,0 @@ -/* schema.h - * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and - * are covered by the GNU Lesser General Public License, which should be - * included with libxml++ as the file COPYING. - */ - -#ifndef __LIBXMLPP_SCHEMA_H -#define __LIBXMLPP_SCHEMA_H - -#include -#include -#include -#include - -#ifndef LIBXMLXX_DISABLE_DEPRECATED - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -extern "C" { - struct _xmlSchema; -} -#endif //DOXYGEN_SHOULD_SKIP_THIS - -namespace xmlpp -{ - -/** Represents an XML Schema. - * - * @newin{2,24} - * - * @deprecated Use XsdSchema instead. - */ -class Schema : NonCopyable -{ -public: - /** Create a schema from the underlying libxml schema element. - * @deprecated Use XsdSchema instead. - */ - explicit Schema(_xmlSchema* schema); - - /** Create a schema from an XML document. - * @param document XMLSchema document, 0 to create an empty schema document. - * @param embed If true, the document will be deleted when - * the schema is deleted or another document is set. - * @throws xmlpp::parse_error - * @throws xmlpp::internal_error If an empty schema document can't be created. - * @deprecated Use XsdSchema instead. - */ - explicit Schema(Document* document = 0, bool embed = false); - ~Schema(); - - //TODO: Remove virtual when we can break ABI? - - /** Set a new document to the schema. - * If the old schema document is owned by the schema (embed == true), the old - * schema document and all its nodes are deleted. - * @param document XMLSchema document, 0 to create an empty schema document. - * @param embed If true, the document will be deleted when the schema is deleted or another document is set. - * @throws xmlpp::parse_error - * @throws xmlpp::internal_error If an empty schema document can't be created. - * @deprecated Use XsdSchema::parse_document() instead. - */ - virtual void set_document(Document* document = 0, bool embed = false); - - /** @deprecated There is no replacement. - */ - Glib::ustring get_name() const; - - /** @deprecated There is no replacement. - */ - Glib::ustring get_target_namespace() const; - - /** @deprecated There is no replacement. - */ - Glib::ustring get_version() const; - - /** Get the schema document. - * @returns A pointer to the schema document, or 0 if none exists. - * @deprecated There is no replacement. - */ - Document* get_document(); - - /** Get the schema document. - * @returns A pointer to the schema document, or 0 if none exists. - * @deprecated There is no replacement. - */ - const Document* get_document() const; - - /** Access the underlying libxml implementation. - * @deprecated Use XsdSchema::cobj() instead. - */ - _xmlSchema* cobj(); - - /** Access the underlying libxml implementation. - * @deprecated Use XsdSchema::cobj() instead. - */ - const _xmlSchema* cobj() const; - -protected: - virtual void release_underlying(); - -private: - _xmlSchema* impl_; - - /** If the base document is created with the schema. */ - bool embedded_doc_; -}; - -} // namespace xmlpp - -#endif // LIBXMLXX_DISABLE_DEPRECATED -#endif //__LIBXMLPP_SCHEMA_H diff --git a/libxml++/schemabase.cc b/libxml++/schemabase.cc index 02eb660c..aec357b5 100644 --- a/libxml++/schemabase.cc +++ b/libxml++/schemabase.cc @@ -21,7 +21,7 @@ namespace xmlpp { -SchemaBase::SchemaBase() +SchemaBase::SchemaBase() noexcept { } diff --git a/libxml++/schemabase.h b/libxml++/schemabase.h index 8f61226e..690327ef 100644 --- a/libxml++/schemabase.h +++ b/libxml++/schemabase.h @@ -20,11 +20,8 @@ #define __LIBXMLPP_SCHEMABASE_H #include - -namespace Glib -{ -class ustring; -} +#include +#include namespace xmlpp { @@ -34,10 +31,10 @@ class Document; * * @newin{2,38} */ -class SchemaBase : NonCopyable +class LIBXMLPP_API SchemaBase : public NonCopyable { public: - SchemaBase(); + SchemaBase() noexcept; ~SchemaBase() override; /** Parse a schema definition file. @@ -45,14 +42,14 @@ class SchemaBase : NonCopyable * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - virtual void parse_file(const Glib::ustring& filename) = 0; + virtual void parse_file(const std::string& filename) = 0; /** Parse a schema definition from a string. * If another schema has been parsed before, that schema is replaced by the new one. * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - virtual void parse_memory(const Glib::ustring& contents) = 0; + virtual void parse_memory(const ustring& contents) = 0; /** Parse a schema definition from a document. * If another schema has been parsed before, that schema is replaced by the new one. diff --git a/libxml++/ustring.cc b/libxml++/ustring.cc new file mode 100644 index 00000000..e69de29b diff --git a/libxml++/ustring.h b/libxml++/ustring.h new file mode 100644 index 00000000..97a53461 --- /dev/null +++ b/libxml++/ustring.h @@ -0,0 +1,36 @@ +/* + * Copyright 2020, The libsigc++ Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#ifndef __LIBXMLPP_USTRING_H +#define __LIBXMLPP_USTRING_H + +#include + +namespace xmlpp +{ + +/** This is just an indication to the programmer that the string contains UTF-8. + * On the other hand, when std::string appears in the libxml++ API, the + * encoding of the string may be UTF-8 or may be some other encoding. + */ +using ustring = std::string; + +} // namespace xmlpp + +#endif //__LIBXMLPP_USTRING_H + diff --git a/libxml++/validators/dtdvalidator.cc b/libxml++/validators/dtdvalidator.cc index be4e6cab..1ae700e5 100644 --- a/libxml++/validators/dtdvalidator.cc +++ b/libxml++/validators/dtdvalidator.cc @@ -21,139 +21,157 @@ namespace xmlpp { +struct DtdValidator::Impl +{ + Impl() noexcept : dtd(nullptr), is_dtd_owner(false), context(nullptr) {} + + Dtd* dtd; + bool is_dtd_owner; + _xmlValidCtxt* context; +}; + + DtdValidator::DtdValidator() -: dtd_(nullptr) +: pimpl_(new Impl) { } -DtdValidator::DtdValidator(const Glib::ustring& file) -: dtd_(nullptr) +DtdValidator::DtdValidator(const std::string& filename) +: pimpl_(new Impl) { - parse_subset("",file); + parse_file(filename); } -DtdValidator::DtdValidator(const Glib::ustring& external,const Glib::ustring& system) -: dtd_(nullptr) +DtdValidator::DtdValidator(const ustring& external, const ustring& system) +: pimpl_(new Impl) { - parse_subset(external,system); + parse_subset(external, system); +} + +DtdValidator::DtdValidator(Dtd* dtd, bool take_ownership) +: pimpl_(new Impl) +{ + set_dtd(dtd, take_ownership); } DtdValidator::~DtdValidator() { release_underlying(); - Validator::release_underlying(); } -void DtdValidator::parse_file(const Glib::ustring& filename) +void DtdValidator::parse_file(const std::string& filename) { - parse_subset("",filename); + set_dtd(new Dtd(filename), true); } -void DtdValidator::parse_subset(const Glib::ustring& external,const Glib::ustring& system) +void DtdValidator::parse_subset(const ustring& external, const ustring& system) { - release_underlying(); // Free any existing dtd. - xmlResetLastError(); - - auto dtd = xmlParseDTD( - external.empty() ? 0 : (const xmlChar *)external.c_str(), - system.empty() ? 0 : (const xmlChar *)system.c_str()); - - if (!dtd) - { - throw parse_error("Dtd could not be parsed.\n" + format_xml_error()); - } - - Node::create_wrapper(reinterpret_cast(dtd)); - dtd_ = static_cast(dtd->_private); + set_dtd(new Dtd(external, system), true); } -void DtdValidator::parse_memory(const Glib::ustring& contents) +void DtdValidator::parse_memory(const ustring& contents) { - // Prepare an istream with buffer - std::istringstream is( contents ); - - parse_stream( is ); + std::unique_ptr dtd(new Dtd()); + dtd->parse_memory(contents); + set_dtd(dtd.release(), true); } void DtdValidator::parse_stream(std::istream& in) { - release_underlying(); // Free any existing dtd. - xmlResetLastError(); + std::unique_ptr dtd(new Dtd()); + dtd->parse_stream(in); + set_dtd(dtd.release(), true); +} - IStreamParserInputBuffer ibuff( in ); +void DtdValidator::set_dtd(Dtd* dtd, bool take_ownership) +{ + release_underlying(); + pimpl_->dtd = dtd; + pimpl_->is_dtd_owner = take_ownership; +} - auto dtd = xmlIOParseDTD( 0, ibuff.cobj(), XML_CHAR_ENCODING_UTF8 ); +void DtdValidator::initialize_context() +{ + Validator::initialize_context(); - if (!dtd) + if (pimpl_->context) { - throw parse_error("Dtd could not be parsed.\n" + format_xml_error()); - } + //Tell the validation context about the callbacks: + pimpl_->context->error = get_callback_validity_error_cfunc(); + pimpl_->context->warning = get_callback_validity_warning_cfunc(); - Node::create_wrapper(reinterpret_cast(dtd)); - dtd_ = static_cast(dtd->_private); + //Allow the callback_validity_*() methods to retrieve the C++ instance: + pimpl_->context->userData = this; + } } void DtdValidator::release_underlying() { - if(dtd_) + if (pimpl_->context) { - //Make a local pointer to the underlying xmlDtd object as the wrapper is destroyed first. - //After free_wrappers is called dtd_ will be invalid (e.g. delete dtd_) - auto dtd = dtd_->cobj(); - Node::free_wrappers(reinterpret_cast(dtd)); - xmlFreeDtd(dtd); - dtd_ = nullptr; + pimpl_->context->userData = nullptr; //Not really necessary. + + xmlFreeValidCtxt(pimpl_->context); + pimpl_->context = nullptr; + } + + if (pimpl_->dtd) + { + if (pimpl_->is_dtd_owner) + delete pimpl_->dtd; + pimpl_->dtd = nullptr; } + + Validator::release_underlying(); } -DtdValidator::operator bool() const +DtdValidator::operator bool() const noexcept { - return dtd_ != nullptr; + return pimpl_->dtd && pimpl_->dtd->cobj(); } -Dtd* DtdValidator::get_dtd() +Dtd* DtdValidator::get_dtd() noexcept { - return dtd_; + return pimpl_->dtd; } -const Dtd* DtdValidator::get_dtd() const +const Dtd* DtdValidator::get_dtd() const noexcept { - return dtd_; + return pimpl_->dtd; } -bool DtdValidator::validate(const Document* doc) +void DtdValidator::validate(const Document* document) { - if (!doc) + if (!document) { - throw internal_error("Document pointer cannot be 0."); + throw internal_error("Document pointer cannot be nullptr."); } - if (!dtd_) + if (!pimpl_->dtd) { throw internal_error("No DTD to use for validation."); } // A context is required at this stage only - if (!valid_) - valid_ = xmlNewValidCtxt(); + if (!pimpl_->context) + pimpl_->context = xmlNewValidCtxt(); - if(!valid_) + if (!pimpl_->context) { throw internal_error("Couldn't create validation context"); } xmlResetLastError(); - initialize_valid(); + initialize_context(); - const bool res = (bool)xmlValidateDtd( valid_, (xmlDoc*)doc->cobj(), dtd_->cobj() ); + const auto res = (bool)xmlValidateDtd(pimpl_->context, (xmlDoc*)document->cobj(), + pimpl_->dtd->cobj()); if (!res) { check_for_exception(); throw validity_error("Document failed DTD validation\n" + format_xml_error()); } - - return res; } } // namespace xmlpp diff --git a/libxml++/validators/dtdvalidator.h b/libxml++/validators/dtdvalidator.h index 01b04c1f..4e713c8e 100644 --- a/libxml++/validators/dtdvalidator.h +++ b/libxml++/validators/dtdvalidator.h @@ -1,4 +1,4 @@ -/* xml++.h +/* dtdvalidator.h * libxml++ and this file are copyright (C) 2000 by Ari Johnson, * (C) 2002-2004 by the libxml dev team and * are covered by the GNU Lesser General Public License, which should be @@ -15,90 +15,135 @@ namespace xmlpp { /** XML DTD validator. + * DTD = %Document Type Definition */ class DtdValidator : public Validator { public: - DtdValidator(); + LIBXMLPP_API DtdValidator(); /** Create a validator and parse an external subset (DTD file) immediately. - * @param file The URL of the DTD. + * @param filename The URL of the DTD. * @throws xmlpp::parse_error */ - explicit DtdValidator(const Glib::ustring& file); + LIBXMLPP_API + explicit DtdValidator(const std::string& filename); /** Create a validator and parse an external subset (DTD file) immediately. * @param external The external ID of the DTD. * @param system The URL of the DTD. * @throws xmlpp::parse_error */ - explicit DtdValidator(const Glib::ustring& external,const Glib::ustring& system); - - ~DtdValidator() override; + LIBXMLPP_API + explicit DtdValidator(const ustring& external, const ustring& system); + + /** Create a validator. + * + * @newin{3,0} + * + * @param dtd A pointer to the DTD to use when validating XML documents. + * @param take_ownership If true, the validator takes ownership of + * the DTD. The caller must not delete it.
+ * If false, the validator does not take ownership of the DTD. + * The caller must guarantee that the DTD exists as long as the + * validator keeps a pointer to it. The caller is responsible for + * deleting the DTD when it's no longer needed. + */ + LIBXMLPP_API + explicit DtdValidator(Dtd* dtd, bool take_ownership); - //TODO: Remove virtuals when we can break ABI, - //or really put these in the base class. + LIBXMLPP_API ~DtdValidator() override; /** Parse an external subset (DTD file). * If the validator already contains a DTD, that DTD is deleted. - * @param external The external ID of the DTD. - * @param system The URL of the DTD. + * @param filename The URL of the DTD. * @throws xmlpp::parse_error */ - virtual void parse_subset(const Glib::ustring& external,const Glib::ustring& system); + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse an external subset (DTD file). * If the validator already contains a DTD, that DTD is deleted. - * @param filename The URL of the DTD. + * @param external The external ID of the DTD. + * @param system The URL of the DTD. * @throws xmlpp::parse_error */ - virtual void parse_file(const Glib::ustring& filename); + LIBXMLPP_API + void parse_subset(const ustring& external, const ustring& system); /** Parse a DTD from a string. * If the validator already contains a DTD, that DTD is deleted. * @param contents The DTD as a string. * @throws xmlpp::parse_error */ - virtual void parse_memory(const Glib::ustring& contents); + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse a DTD from a stream. * If the validator already contains a DTD, that DTD is deleted. * @param in The stream. * @throws xmlpp::parse_error */ - virtual void parse_stream(std::istream& in); + LIBXMLPP_API + void parse_stream(std::istream& in); + + /** Set a DTD. + * If the validator already contains a DTD, that DTD is released + * (deleted if the validator owns the DTD). + * @param dtd A pointer to the DTD to use when validating XML documents. + * @param take_ownership If true, the validator takes ownership of + * the DTD. The caller must not delete it.
+ * If false, the validator does not take ownership of the DTD. + * The caller must guarantee that the DTD exists as long as the + * validator keeps a pointer to it. The caller is responsible for + * deleting the DTD when it's no longer needed. + */ + LIBXMLPP_API + void set_dtd(Dtd* dtd, bool take_ownership); /** Test whether a DTD has been parsed. + * For instance + * @code + * if (validator) + * do_something(); + * @endcode */ - operator bool() const; + LIBXMLPP_API + explicit operator bool() const noexcept override; /** Get the parsed DTD. - * @returns A pointer to the parsed DTD, or 0. + * @returns A pointer to the parsed DTD, or nullptr. */ - Dtd* get_dtd(); + LIBXMLPP_API + Dtd* get_dtd() noexcept; /** Get the parsed DTD. - * @returns A pointer to the parsed DTD, or 0. + * @returns A pointer to the parsed DTD, or nullptr. */ - const Dtd* get_dtd() const; + LIBXMLPP_API + const Dtd* get_dtd() const noexcept; /** Validate a document, using a previously parsed DTD. * The internal subset (if present) is de-coupled (i.e. not used), * which could give problems if ID or IDREF is present. - * @param doc Pointer to the document. - * @returns Whether the document is valid. + * @param document Pointer to the document. * @throws xmlpp::internal_error * @throws xmlpp::validity_error */ - bool validate(const Document* doc); + LIBXMLPP_API + void validate(const Document* document) override; protected: + LIBXMLPP_API + void initialize_context() override; + LIBXMLPP_API void release_underlying() override; - Dtd* dtd_; +private: + struct Impl; + std::unique_ptr pimpl_; }; } // namespace xmlpp #endif //__LIBXMLPP_VALIDATORS_DTDVALIDATOR_H - diff --git a/libxml++/validators/relaxngvalidator.cc b/libxml++/validators/relaxngvalidator.cc index 0d00560c..68a814c0 100644 --- a/libxml++/validators/relaxngvalidator.cc +++ b/libxml++/validators/relaxngvalidator.cc @@ -22,6 +22,7 @@ #include "libxml++/parsers/domparser.h" #include "libxml++/relaxngschema.h" +#include #include namespace xmlpp @@ -29,7 +30,7 @@ namespace xmlpp struct RelaxNGValidator::Impl { - Impl() : schema(nullptr), is_schema_owner(false), context(nullptr) {} + Impl() noexcept : schema(nullptr), is_schema_owner(false), context(nullptr) {} RelaxNGSchema* schema; bool is_schema_owner; @@ -42,7 +43,7 @@ RelaxNGValidator::RelaxNGValidator() { } -RelaxNGValidator::RelaxNGValidator(const Glib::ustring& filename) +RelaxNGValidator::RelaxNGValidator(const std::string& filename) : pimpl_(new Impl) { parse_file(filename); @@ -65,12 +66,12 @@ RelaxNGValidator::~RelaxNGValidator() release_underlying(); } -void RelaxNGValidator::parse_file(const Glib::ustring& filename) +void RelaxNGValidator::parse_file(const std::string& filename) { set_schema(new RelaxNGSchema(filename), true); } -void RelaxNGValidator::parse_memory(const Glib::ustring& contents) +void RelaxNGValidator::parse_memory(const ustring& contents) { std::unique_ptr schema(new RelaxNGSchema()); schema->parse_memory(contents); @@ -107,32 +108,33 @@ void RelaxNGValidator::release_underlying() SchemaValidatorBase::release_underlying(); } -RelaxNGSchema* RelaxNGValidator::get_schema() +RelaxNGSchema* RelaxNGValidator::get_schema() noexcept { return pimpl_->schema; } -const RelaxNGSchema* RelaxNGValidator::get_schema() const +const RelaxNGSchema* RelaxNGValidator::get_schema() const noexcept { return pimpl_->schema; } -RelaxNGValidator::operator const void*() const +RelaxNGValidator::operator bool() const noexcept { - return reinterpret_cast(pimpl_->schema && pimpl_->schema->cobj()); + return pimpl_->schema && pimpl_->schema->cobj(); } -void RelaxNGValidator::initialize_valid() +void RelaxNGValidator::initialize_context() { - xmlRelaxNGSetValidErrors(pimpl_->context, &callback_validity_error, &callback_validity_warning, this); - SchemaValidatorBase::initialize_valid(); + xmlRelaxNGSetValidErrors(pimpl_->context, get_callback_validity_error_cfunc(), + get_callback_validity_warning_cfunc(), this); + SchemaValidatorBase::initialize_context(); } void RelaxNGValidator::validate(const Document* document) { if (!document) - throw internal_error("RelaxNGValidator::validate(): document must not be 0."); + throw internal_error("RelaxNGValidator::validate(): document must not be nullptr."); if (!*this) throw internal_error("RelaxNGValidator::validate(): Must have a schema to validate document"); @@ -145,7 +147,7 @@ void RelaxNGValidator::validate(const Document* document) throw internal_error("RelaxNGValidator::validate(): Could not create validating context"); xmlResetLastError(); - initialize_valid(); + initialize_context(); const int res = xmlRelaxNGValidateDoc(pimpl_->context, const_cast(document->cobj())); if (res != 0) @@ -154,12 +156,12 @@ void RelaxNGValidator::validate(const Document* document) auto error_str = format_xml_error(); if (error_str.empty()) - error_str = "Error code from xmlRelaxNGValidateDoc(): " + Glib::ustring::format(res); + error_str = "Error code from xmlRelaxNGValidateDoc(): " + std::to_string(res); throw validity_error("Document failed RelaxNG schema validation.\n" + error_str); } } -void RelaxNGValidator::validate(const Glib::ustring& filename) +void RelaxNGValidator::validate(const std::string& filename) { // There is no xmlRelaxNGValidateFile(). DomParser parser(filename); diff --git a/libxml++/validators/relaxngvalidator.h b/libxml++/validators/relaxngvalidator.h index f9138a3a..1f117dcc 100644 --- a/libxml++/validators/relaxngvalidator.h +++ b/libxml++/validators/relaxngvalidator.h @@ -22,12 +22,7 @@ #define __LIBXMLPP_VALIDATOR_RELAXNGVALIDATOR_H #include -#include // std::auto_ptr - -namespace Glib -{ -class ustring; -} +#include // std::unique_ptr namespace xmlpp { @@ -42,7 +37,7 @@ class RelaxNGSchema; class RelaxNGValidator : public SchemaValidatorBase { public: - RelaxNGValidator(); + LIBXMLPP_API RelaxNGValidator(); /** Create a validator and parse a schema definition file. * The schema must be defined with XML syntax (.rng file). The compact syntax @@ -50,12 +45,14 @@ class RelaxNGValidator : public SchemaValidatorBase * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - explicit RelaxNGValidator(const Glib::ustring& filename); + LIBXMLPP_API + explicit RelaxNGValidator(const std::string& filename); /** Create a validator and parse a schema definition document. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API explicit RelaxNGValidator(const Document* document); /** Create a validator. @@ -67,12 +64,10 @@ class RelaxNGValidator : public SchemaValidatorBase * validator keeps a pointer to it. The caller is responsible for * deleting the schema when it's no longer needed. */ + LIBXMLPP_API explicit RelaxNGValidator(RelaxNGSchema* schema, bool take_ownership); - ~RelaxNGValidator() override; - - //TODO: Remove virtuals when we can break ABI, - //or really put these in the base class. + LIBXMLPP_API ~RelaxNGValidator() override; /** Parse a schema definition file. * The schema must be defined with XML syntax (.rng file). The compact syntax @@ -83,7 +78,8 @@ class RelaxNGValidator : public SchemaValidatorBase * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - virtual void parse_file(const Glib::ustring& filename); + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse a schema definition from a string. * The schema must be defined with XML syntax. The compact syntax is not supported. @@ -93,7 +89,8 @@ class RelaxNGValidator : public SchemaValidatorBase * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - virtual void parse_memory(const Glib::ustring& contents); + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse a schema definition from a document. * If the validator already contains a schema, that schema is released @@ -101,7 +98,8 @@ class RelaxNGValidator : public SchemaValidatorBase * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ - virtual void parse_document(const Document* document); + LIBXMLPP_API + void parse_document(const Document* document) override; /** Set a schema. * If the validator already contains a schema, that schema is released @@ -114,6 +112,7 @@ class RelaxNGValidator : public SchemaValidatorBase * validator keeps a pointer to it. The caller is responsible for * deleting the schema when it's no longer needed. */ + LIBXMLPP_API void set_schema(RelaxNGSchema* schema, bool take_ownership); /** Test whether a schema has been parsed. @@ -123,24 +122,28 @@ class RelaxNGValidator : public SchemaValidatorBase * do_something(); * @endcode */ - virtual operator BoolExpr() const; + LIBXMLPP_API + explicit operator bool() const noexcept override; /** Get the schema. - * @returns A pointer to the schema, or 0. + * @returns A pointer to the schema, or nullptr. */ - RelaxNGSchema* get_schema(); + LIBXMLPP_API + RelaxNGSchema* get_schema() noexcept; /** Get the schema. - * @returns A pointer to the schema, or 0. + * @returns A pointer to the schema, or nullptr. */ - const RelaxNGSchema* get_schema() const; + LIBXMLPP_API + const RelaxNGSchema* get_schema() const noexcept; /** Validate a document, using a previously parsed schema. * @param document Pointer to the document. * @throws xmlpp::internal_error * @throws xmlpp::validity_error */ - virtual void validate(const Document* document); + LIBXMLPP_API + void validate(const Document* document) override; /** Validate an XML file, using a previously parsed schema. * @param filename The URL of the XML file. @@ -148,15 +151,18 @@ class RelaxNGValidator : public SchemaValidatorBase * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - virtual void validate(const Glib::ustring& filename); + LIBXMLPP_API + void validate(const std::string& filename) override; protected: - void initialize_valid() override; + LIBXMLPP_API + void initialize_context() override; + LIBXMLPP_API void release_underlying() override; private: struct Impl; - std::auto_ptr pimpl_; + std::unique_ptr pimpl_; }; } // namespace xmlpp diff --git a/libxml++/validators/schemavalidator.cc b/libxml++/validators/schemavalidator.cc deleted file mode 100644 index a3c239a2..00000000 --- a/libxml++/validators/schemavalidator.cc +++ /dev/null @@ -1,232 +0,0 @@ -/* dtdvalidator.cpp - * libxml++ and this file are copyright (C) 2000 by Ari Johnson - * (C) 2002-2004 by the libxml dev team and - * are covered by the GNU Lesser General Public License, which should be - * included with libxml++ as the file COPYING. - */ - -#include // LIBXMLXX_DISABLE_DEPRECATED - -#ifndef LIBXMLXX_DISABLE_DEPRECATED - -#include "libxml++/validators/schemavalidator.h" -#include "libxml++/schema.h" - -#include -#include - -#include -#include - -namespace -{ - // This class simply holds a xmlSchemaParserCtxtPtr and releases it on - // destruction. This way, we make sure we don't leak it in either case, - // even when an exception is thrown. - class XmlSchemaParserContextHolder - { - public: - XmlSchemaParserContextHolder(xmlSchemaParserCtxtPtr ptr): ptr_(ptr) {} - ~XmlSchemaParserContextHolder() { xmlSchemaFreeParserCtxt(ptr_); } - - private: - xmlSchemaParserCtxtPtr ptr_; - }; -} - -namespace xmlpp -{ - -SchemaValidator::SchemaValidator() -: schema_(nullptr) -, embbeded_shema_(false) -, ctxt_(nullptr) -{ -} - -SchemaValidator::SchemaValidator(const Glib::ustring& file) -: schema_(nullptr) -, embbeded_shema_(false) -, ctxt_(nullptr) -{ - parse_file( file ); -} - -SchemaValidator::SchemaValidator(Document& document) -: schema_(nullptr) -, embbeded_shema_(false) -, ctxt_(nullptr) -{ - parse_document( document ); -} - -SchemaValidator::SchemaValidator(Schema* schema) -: schema_(schema) -, embbeded_shema_(false) -, ctxt_(nullptr) -{ -} - -SchemaValidator::~SchemaValidator() -{ - release_underlying(); - Validator::release_underlying(); -} - -void SchemaValidator::parse_context(_xmlSchemaParserCtxt* context) -{ - if (!context) - throw parse_error("Could not create schema parser context\n" + format_xml_error()); - - release_underlying(); // Free any existing schema. - - auto schema = xmlSchemaParse( context ); - if ( ! schema ) - throw parse_error("Schema could not be parsed\n" + format_xml_error()); - - schema->_private = new Schema(schema); - - schema_ = static_cast(schema->_private); - embbeded_shema_ = true; -} - -void SchemaValidator::parse_file(const Glib::ustring& filename) -{ - xmlResetLastError(); - auto ctx = xmlSchemaNewParserCtxt( filename.c_str() ); - XmlSchemaParserContextHolder holder(ctx); - parse_context( ctx ); -} - -void SchemaValidator::parse_memory(const Glib::ustring& contents) -{ - xmlResetLastError(); - auto ctx = xmlSchemaNewMemParserCtxt( contents.c_str(), contents.bytes() ); - XmlSchemaParserContextHolder holder(ctx); - parse_context( ctx ); -} - -void SchemaValidator::parse_document(Document& document) -{ - xmlResetLastError(); - auto ctx = xmlSchemaNewDocParserCtxt( document.cobj() ); - XmlSchemaParserContextHolder holder(ctx); - parse_context( ctx ); -} - -void SchemaValidator::set_schema(Schema* schema) -{ - release_underlying(); - schema_ = schema; - embbeded_shema_ = false; -} - -void SchemaValidator::release_underlying() -{ - if(ctxt_) - { - xmlSchemaFreeValidCtxt( ctxt_ ); - ctxt_ = nullptr; - } - if(schema_) - { - if(embbeded_shema_) - delete schema_; - schema_ = nullptr; - } -} - -SchemaValidator::operator bool() const -{ - return schema_ != nullptr; -} - -Schema* SchemaValidator::get_schema() -{ - return schema_; -} - -const Schema* SchemaValidator::get_schema() const -{ - return schema_; -} - -void SchemaValidator::initialize_valid() -{ - xmlSchemaSetValidErrors(ctxt_, &callback_validity_error, &callback_validity_warning, this); - Validator::initialize_valid(); -} - - -bool SchemaValidator::validate(const Document* doc) -{ - if (!doc) - throw internal_error("Document pointer cannot be 0"); - - if (!schema_) - throw internal_error("Must have a schema to validate document"); - - // A context is required at this stage only - if (!ctxt_) - ctxt_ = xmlSchemaNewValidCtxt( schema_->cobj() ); - - if(!ctxt_) - { - throw internal_error("Couldn't create validating context"); - } - - xmlResetLastError(); - initialize_valid(); - - const int res = xmlSchemaValidateDoc( ctxt_, (xmlDoc*)doc->cobj() ); - - if(res != 0) - { - check_for_exception(); - - auto error_str = format_xml_error(); - if (error_str.empty()) - error_str = "Error code from xmlSchemaValidateDoc(): " + Glib::ustring::format(res); - throw validity_error("Document failed schema validation\n" + error_str); - } - - return res == 0; -} - -bool SchemaValidator::validate(const Glib::ustring& file) -{ - if (file.empty()) - throw internal_error("File path must not be empty"); - - if (!schema_) - throw internal_error("Must have a schema to validate document"); - - // A context is required at this stage only - if (!ctxt_) - ctxt_ = xmlSchemaNewValidCtxt( schema_->cobj() ); - - if(!ctxt_) - { - throw internal_error("Couldn't create validating context"); - } - - xmlResetLastError(); - initialize_valid(); - - const int res = xmlSchemaValidateFile( ctxt_, file.c_str(), 0 ); - - if(res != 0) - { - check_for_exception(); - - auto error_str = format_xml_error(); - if (error_str.empty()) - error_str = "Error code from xmlSchemaValidateFile(): " + Glib::ustring::format(res); - throw validity_error("Document failed schema validation\n" + error_str); - } - - return res == 0; -} - -} // namespace xmlpp -#endif // LIBXMLXX_DISABLE_DEPRECATED diff --git a/libxml++/validators/schemavalidator.h b/libxml++/validators/schemavalidator.h deleted file mode 100644 index 07d7eae4..00000000 --- a/libxml++/validators/schemavalidator.h +++ /dev/null @@ -1,155 +0,0 @@ -/* schemavalidator.h - * libxml++ and this file are copyright (C) 2000 by Ari Johnson, - * (C) 2002-2004 by the libxml dev team and - * are covered by the GNU Lesser General Public License, which should be - * included with libxml++ as the file COPYING. - */ - -#ifndef __LIBXMLPP_VALIDATOR_SCHEMAVALIDATOR_H -#define __LIBXMLPP_VALIDATOR_SCHEMAVALIDATOR_H - -#include -#include -#include - -#ifndef LIBXMLXX_DISABLE_DEPRECATED - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -extern "C" { - struct _xmlSchemaParserCtxt; - struct _xmlSchemaValidCtxt; -} -#endif //DOXYGEN_SHOULD_SKIP_THIS - -namespace xmlpp { - -/** XML Schema Validator. - * - * @newin{2,24} - * - * @deprecated Use XsdValidator instead. - */ -class SchemaValidator : public Validator -{ -public: - SchemaValidator(); - - /** Create a validator and parse a schema definition file immediately. - * @param file The URL of the schema. - * @throws xmlpp::parse_error - * @deprecated Use XsdValidator instead. - */ - explicit SchemaValidator(const Glib::ustring& file); - - /** Create a validator and parse a schema definition document immediately. - * @param document A preparsed document tree, containing the schema definition. - * @note The document may be modified during the parsing process. - * @throws xmlpp::parse_error - * @deprecated Use XsdValidator instead. - */ - explicit SchemaValidator(Document& document); - - /** Create a schema validator. - * @param schema A pointer to the XML schema to use when validating XML documents. - * The validator does not take ownership of the schema. The caller must - * guarantee that the schema exists as long as the validator keeps a - * pointer to it. The caller is responsible for deleting the schema - * when it's no longer needed. - * @deprecated Use XsdValidator instead. - */ - explicit SchemaValidator(Schema* schema); - - ~SchemaValidator() override; - - //TODO: Remove virtuals when we can break ABI, - //or really put these in the base class. - - /** Parse a schema definition file. - * If the validator already contains a schema, that schema is released - * (deleted if the validator owns the schema). - * @param filename The URL of the schema. - * @throws xmlpp::parse_error - * @deprecated Use XsdValidator::parse_file() instead. - */ - virtual void parse_file(const Glib::ustring& filename); - - /** Parse a schema definition from a string. - * If the validator already contains a schema, that schema is released - * (deleted if the validator owns the schema). - * @param contents The schema definition as a string. - * @throws xmlpp::parse_error - * @deprecated Use XsdValidator::parse_memory() instead. - */ - virtual void parse_memory(const Glib::ustring& contents); - - /** Parse a schema definition from a document. - * If the validator already contains a schema, that schema is released - * (deleted if the validator owns the schema). - * @param document A preparsed document tree, containing the schema definition. - * @note The document may be modified during the parsing process. - * @throws xmlpp::parse_error - * @deprecated Use XsdValidator::parse_document() instead. - */ - virtual void parse_document(Document& document); - - /** Set a schema. - * If the validator already contains a schema, that schema is released - * (deleted if the validator owns the schema). - * @param schema A pointer to the XML schema to use when validating XML documents. - * The validator does not take ownership of the schema. The caller must - * guarantee that the schema exists as long as the validator keeps a - * pointer to it. The caller is responsible for deleting the schema - * when it's no longer needed. - * @deprecated Use XsdValidator::set_schema() instead. - */ - virtual void set_schema(Schema* schema); - - /** Test whether a schema has been parsed. - * @deprecated Use XsdValidator::operator BoolExpr() instead. - */ - operator bool() const; - - /** Get the parsed schema. - * @returns A pointer to the parsed schema, or 0. - * @deprecated Use XsdValidator::get_schema() instead. - */ - Schema* get_schema(); - - /** Get the parsed schema. - * @returns A pointer to the parsed schema, or 0. - * @deprecated Use XsdValidator::get_schema() instead. - */ - const Schema* get_schema() const; - - /** Validate a document, using a previously parsed schema. - * @param doc Pointer to the document. - * @returns Whether the document is valid. - * @throws xmlpp::internal_error - * @throws xmlpp::validity_error - * @deprecated Use XsdValidator::validate(const Document*) instead. - */ - bool validate(const Document* doc); - - /** Validate an XML file, using a previously parsed schema. - * @param file The URI of the XML file. - * @returns Whether the document is valid. - * @throws xmlpp::internal_error - * @throws xmlpp::validity_error - * @deprecated Use XsdValidator::validate(const Glib::ustring&) instead. - */ - bool validate(const Glib::ustring& file); - -protected: - void initialize_valid() override; - void parse_context(_xmlSchemaParserCtxt* context); - void release_underlying() override; - - Schema* schema_; - bool embbeded_shema_; //TODO Correct mis-spelling at the next API/ABI break. - _xmlSchemaValidCtxt* ctxt_; -}; - -} // namespace xmlpp - -#endif // LIBXMLXX_DISABLE_DEPRECATED -#endif //__LIBXMLPP_VALIDATOR_SCHEMAVALIDATOR_H diff --git a/libxml++/validators/schemavalidatorbase.cc b/libxml++/validators/schemavalidatorbase.cc index 04aa74c7..bbd1898a 100644 --- a/libxml++/validators/schemavalidatorbase.cc +++ b/libxml++/validators/schemavalidatorbase.cc @@ -22,7 +22,7 @@ namespace xmlpp { -SchemaValidatorBase::SchemaValidatorBase() +SchemaValidatorBase::SchemaValidatorBase() noexcept { } @@ -36,9 +36,9 @@ void SchemaValidatorBase::release_underlying() Validator::release_underlying(); } -void SchemaValidatorBase::initialize_valid() +void SchemaValidatorBase::initialize_context() { - Validator::initialize_valid(); + Validator::initialize_context(); } } // namespace xmlpp diff --git a/libxml++/validators/schemavalidatorbase.h b/libxml++/validators/schemavalidatorbase.h index 02b63a7e..a7f1a508 100644 --- a/libxml++/validators/schemavalidatorbase.h +++ b/libxml++/validators/schemavalidatorbase.h @@ -20,12 +20,6 @@ #define __LIBXMLPP_VALIDATOR_SCHEMAVALIDATORBASE_H #include -#include // std::auto_ptr - -namespace Glib -{ -class ustring; -} namespace xmlpp { @@ -38,11 +32,8 @@ class Document; class SchemaValidatorBase : public Validator { public: - SchemaValidatorBase(); - ~SchemaValidatorBase() override; - - //TODO: Remove virtuals when we can break ABI, - //or really put these in the base class. + LIBXMLPP_API SchemaValidatorBase() noexcept; + LIBXMLPP_API ~SchemaValidatorBase() override; /** Parse a schema definition file. * If the validator already contains a schema, that schema is released @@ -50,7 +41,8 @@ class SchemaValidatorBase : public Validator * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - virtual void parse_file(const Glib::ustring& filename) = 0; + LIBXMLPP_API + void parse_file(const std::string& filename) override = 0; /** Parse a schema definition from a string. * If the validator already contains a schema, that schema is released @@ -58,7 +50,8 @@ class SchemaValidatorBase : public Validator * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - virtual void parse_memory(const Glib::ustring& contents) = 0; + LIBXMLPP_API + void parse_memory(const ustring& contents) override = 0; /** Parse a schema definition from a document. * If the validator already contains a schema, that schema is released @@ -66,13 +59,9 @@ class SchemaValidatorBase : public Validator * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API virtual void parse_document(const Document* document) = 0; - /** This typedef is just to make it more obvious that - * our operator const void* should be used like operator bool(). - */ - typedef const void* BoolExpr; - /** Test whether a schema has been parsed. * For instance * @code @@ -80,14 +69,16 @@ class SchemaValidatorBase : public Validator * do_something(); * @endcode */ - virtual operator BoolExpr() const = 0; + LIBXMLPP_API + explicit operator bool() const noexcept override = 0; /** Validate a document, using a previously parsed schema. * @param document Pointer to the document. * @throws xmlpp::internal_error * @throws xmlpp::validity_error */ - virtual void validate(const Document* document) = 0; + LIBXMLPP_API + void validate(const Document* document) override = 0; /** Validate an XML file, using a previously parsed schema. * @param filename The URL of the XML file. @@ -95,10 +86,13 @@ class SchemaValidatorBase : public Validator * @throws xmlpp::parse_error * @throws xmlpp::validity_error */ - virtual void validate(const Glib::ustring& filename) = 0; + LIBXMLPP_API + virtual void validate(const std::string& filename) = 0; protected: - void initialize_valid() override; + LIBXMLPP_API + void initialize_context() override; + LIBXMLPP_API void release_underlying() override; }; diff --git a/libxml++/validators/validator.cc b/libxml++/validators/validator.cc index 220d4598..25889b29 100644 --- a/libxml++/validators/validator.cc +++ b/libxml++/validators/validator.cc @@ -1,4 +1,4 @@ -/* xml++.cc +/* validator.cc * libxml++ and this file are copyright (C) 2000 by Ari Johnson * (C) 2002-2004 by the libxml dev team and * are covered by the GNU Lesser General Public License, which should be @@ -13,10 +13,37 @@ #include //For va_list. #include //For unique_ptr. +namespace +{ +// C++ linkage +using ErrorOrWarningFuncType = void (*)(bool error, void* ctx, + const char* msg, va_list var_args); +ErrorOrWarningFuncType p_callback_error_or_warning; + +extern "C" +{ +static void c_callback_validity_error(void* ctx, const char* msg, ...) +{ + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(true, ctx, msg, var_args); + va_end(var_args); +} + +static void c_callback_validity_warning(void* ctx, const char* msg, ...) +{ + va_list var_args; + va_start(var_args, msg); + p_callback_error_or_warning(false, ctx, msg, var_args); + va_end(var_args); +} +} // extern "C" +} // anonymous namespace + namespace xmlpp { -Validator::Validator() -: valid_(nullptr), exception_(nullptr) +Validator::Validator() noexcept +: exception_(nullptr) { } @@ -25,43 +52,24 @@ Validator::~Validator() release_underlying(); } -void Validator::initialize_valid() +void Validator::initialize_context() { - // valid_ is used only by DtdValidator. - //TODO: When we can break ABI, move valid_ to DtdValidator. - if (valid_) - { - //Tell the validation context about the callbacks: - valid_->error = &callback_validity_error; - valid_->warning = &callback_validity_warning; - - //Allow the callback_validity_*() methods to retrieve the C++ instance: - valid_->userData = this; - } - - //Clear these temporary buffers too: + //Clear these temporary buffers: validate_error_.erase(); validate_warning_.erase(); } void Validator::release_underlying() { - if(valid_) - { - valid_->userData = nullptr; //Not really necessary. - - xmlFreeValidCtxt(valid_); - valid_ = nullptr; - } } -void Validator::on_validity_error(const Glib::ustring& message) +void Validator::on_validity_error(const ustring& message) { //Throw an exception later when the whole message has been received: validate_error_ += message; } -void Validator::on_validity_warning(const Glib::ustring& message) +void Validator::on_validity_warning(const ustring& message) { //Throw an exception later when the whole message has been received: validate_warning_ += message; @@ -69,7 +77,7 @@ void Validator::on_validity_warning(const Glib::ustring& message) void Validator::check_for_validity_messages() { - Glib::ustring msg(exception_ ? exception_->what() : ""); + ustring msg(exception_ ? exception_->what() : ""); bool validity_msg = false; if (!validate_error_.empty()) @@ -87,12 +95,10 @@ void Validator::check_for_validity_messages() } if (validity_msg) - { - delete exception_; - exception_ = new validity_error(msg); - } + exception_ = std::make_unique(msg); } +#ifndef LIBXMLXX_DISABLE_DEPRECATED void Validator::callback_validity_error(void* valid_, const char* msg, ...) { auto validator = static_cast(valid_); @@ -101,23 +107,17 @@ void Validator::callback_validity_error(void* valid_, const char* msg, ...) { //Convert the ... to a string: va_list arg; - char buff[1024]; //TODO: Larger/Shared - va_start(arg, msg); - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg); + const ustring buff = format_printf_message(msg, arg); va_end(arg); try { - validator->on_validity_error(Glib::ustring(buff)); - } - catch(const exception& e) - { - validator->handleException(e); + validator->on_validity_error(buff); } - catch(...) + catch (...) { - validator->handleException(wrapped_exception(std::current_exception())); + validator->handle_exception(); } } } @@ -130,36 +130,94 @@ void Validator::callback_validity_warning(void* valid_, const char* msg, ...) { //Convert the ... to a string: va_list arg; - char buff[1024]; //TODO: Larger/Shared - va_start(arg, msg); - vsnprintf(buff, sizeof(buff)/sizeof(buff[0]), msg, arg); + const ustring buff = format_printf_message(msg, arg); va_end(arg); try { - validator->on_validity_warning(Glib::ustring(buff)); + validator->on_validity_warning(buff); + } + catch (...) + { + validator->handle_exception(); } - catch(const exception& e) + } +} +#endif // LIBXMLXX_DISABLE_DEPRECATED + +//static +ValidatorCallbackCFuncType Validator::get_callback_validity_error_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_validity_error; +} + +//static +ValidatorCallbackCFuncType Validator::get_callback_validity_warning_cfunc() +{ + p_callback_error_or_warning = &callback_error_or_warning; + return &c_callback_validity_warning; +} + +//static +void Validator::callback_error_or_warning(bool error, void* ctx, + const char* msg, va_list var_args) +{ + // The caller of a libxml2 function with a callback is assumed to have + // specified that the validation context is a xmlpp::Validator instance. + auto validator = static_cast(ctx); + + if (validator) + { + // Convert msg and var_args to a string: + const ustring buff = format_printf_message(msg, var_args); + + try { - validator->handleException(e); + if (error) + validator->on_validity_error(buff); + else + validator->on_validity_warning(buff); } - catch(...) + catch (...) { - validator->handleException(wrapped_exception(std::current_exception())); + validator->handle_exception(); } } } -void Validator::handleException(const exception& e) +void Validator::handle_exception() { - delete exception_; - exception_ = e.Clone(); + try + { + throw; // Re-throw current exception + } + catch (const exception& e) + { + exception_.reset(e.clone()); + } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR + catch (...) + { + exception_ = std::make_unique(std::current_exception()); + } +#else + catch (const std::exception& e) + { + exception_ = std::make_unique(e.what()); + } + catch (...) + { + exception_ = std::make_unique("An exception was thrown that is not derived from std::exception or xmlpp::exception.\n" + "It could not be caught and rethrown because this platform does not support std::exception_ptr."); + } +#endif // Don't delete the DTD validation context or schema validation context // while validating. It would cause accesses to deallocated memory in libxml2 // functions after the return from Validator::callback_validity_...(). - // Parser::handleException() calls xmlStopParser(), but there is no + // Parser::handle_exception() calls xmlStopParser(), but there is no // xmlStopValidator() or similar function to call here. // We don't throw the exception here, since it would have to pass through // C functions. That's not guaranteed to work. It might work, but it depends @@ -172,11 +230,10 @@ void Validator::check_for_exception() { check_for_validity_messages(); - if(exception_) + if (exception_) { - std::unique_ptr tmp(exception_); - exception_ = nullptr; - tmp->Raise(); + std::unique_ptr tmp(std::move(exception_)); + tmp->raise(); } } diff --git a/libxml++/validators/validator.h b/libxml++/validators/validator.h index cdf9f2fc..7f3ec859 100644 --- a/libxml++/validators/validator.h +++ b/libxml++/validators/validator.h @@ -8,13 +8,12 @@ #ifndef __LIBXMLPP_VALIDATOR_H #define __LIBXMLPP_VALIDATOR_H -#ifdef _MSC_VER //Ignore warnings about the Visual C++ Bug, where we can not do anything -#pragma warning (disable : 4786) -#endif - -#include +#include #include #include +#include // va_list +#include // std::unique_ptr +#include extern "C" { struct _xmlValidCtxt; @@ -22,35 +21,101 @@ extern "C" { namespace xmlpp { +extern "C" { + /** Type of function pointer to callback function with C linkage. + * @newin{5,2} + */ + using ValidatorCallbackCFuncType = void (*)(void* ctx, const char* msg, ...); +} + +class Document; + /** Base class for XML validators. */ -class Validator : NonCopyable +class Validator : public NonCopyable { public: - Validator(); - ~Validator() override; + LIBXMLPP_API Validator() noexcept; + LIBXMLPP_API ~Validator() override; + + /** Parse a schema definition file or an external subset (DTD file). + * @param filename The URL of the schema or the DTD. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + virtual void parse_file(const std::string& filename) = 0; + + /** Parse a schema definition or a DTD from a string. + * @param contents The schema definition or the DTD as a string. + * @throws xmlpp::parse_error + */ + LIBXMLPP_API + virtual void parse_memory(const ustring& contents) = 0; + + /** Validate a document, using a previously parsed schema or DTD. + * @param document Pointer to the document. + * @throws xmlpp::internal_error + * @throws xmlpp::validity_error + */ + LIBXMLPP_API + virtual void validate(const Document* document) = 0; + + /** Test whether a schema or a DTD has been parsed. + * For instance + * @code + * if (validator) + * do_something(); + * @endcode + */ + LIBXMLPP_API + explicit virtual operator bool() const noexcept = 0; protected: - virtual void initialize_valid(); + LIBXMLPP_API + virtual void initialize_context(); + LIBXMLPP_API virtual void release_underlying(); - virtual void on_validity_error(const Glib::ustring& message); - virtual void on_validity_warning(const Glib::ustring& message); + LIBXMLPP_API + virtual void on_validity_error(const ustring& message); + LIBXMLPP_API + virtual void on_validity_warning(const ustring& message); - virtual void handleException(const exception& e); + /// To be called in an exception handler. + LIBXMLPP_API + virtual void handle_exception(); + LIBXMLPP_API virtual void check_for_exception(); + LIBXMLPP_API virtual void check_for_validity_messages(); +#ifndef LIBXMLXX_DISABLE_DEPRECATED + /** @deprecated Use get_callback_validity_error_cfunc() instead. */ + LIBXMLPP_API static void callback_validity_error(void* ctx, const char* msg, ...); + /** @deprecated Use get_callback_validity_warning_cfunc() instead. */ + LIBXMLPP_API static void callback_validity_warning(void* ctx, const char* msg, ...); +#endif // LIBXMLXX_DISABLE_DEPRECATED - _xmlValidCtxt* valid_; - exception* exception_; - Glib::ustring validate_error_; - Glib::ustring validate_warning_; //Built gradually - used in an exception at the end of parsing. + /** @newin{5,2} */ + LIBXMLPP_API + static ValidatorCallbackCFuncType get_callback_validity_error_cfunc(); + /** @newin{5,2} */ + LIBXMLPP_API + static ValidatorCallbackCFuncType get_callback_validity_warning_cfunc(); + + /** @newin{5,2} */ + LIBXMLPP_API + static void callback_error_or_warning(bool error, void* ctx, + const char* msg, va_list var_args); + + std::unique_ptr exception_; + // Built gradually - used in an exception at the end of validation. + ustring validate_error_; + ustring validate_warning_; }; } // namespace xmlpp #endif //__LIBXMLPP_VALIDATOR_H - diff --git a/libxml++/validators/xsdvalidator.cc b/libxml++/validators/xsdvalidator.cc index 674296e3..decb8be8 100644 --- a/libxml++/validators/xsdvalidator.cc +++ b/libxml++/validators/xsdvalidator.cc @@ -26,7 +26,7 @@ namespace xmlpp struct XsdValidator::Impl { - Impl() : schema(nullptr), is_schema_owner(false), context(nullptr) {} + Impl() noexcept : schema(nullptr), is_schema_owner(false), context(nullptr) {} XsdSchema* schema; bool is_schema_owner; @@ -39,7 +39,7 @@ XsdValidator::XsdValidator() { } -XsdValidator::XsdValidator(const Glib::ustring& filename) +XsdValidator::XsdValidator(const std::string& filename) : pimpl_(new Impl) { parse_file(filename); @@ -62,12 +62,12 @@ XsdValidator::~XsdValidator() release_underlying(); } -void XsdValidator::parse_file(const Glib::ustring& filename) +void XsdValidator::parse_file(const std::string& filename) { set_schema(new XsdSchema(filename), true); } -void XsdValidator::parse_memory(const Glib::ustring& contents) +void XsdValidator::parse_memory(const ustring& contents) { std::unique_ptr schema(new XsdSchema()); schema->parse_memory(contents); @@ -104,33 +104,34 @@ void XsdValidator::release_underlying() SchemaValidatorBase::release_underlying(); } -XsdSchema* XsdValidator::get_schema() +XsdSchema* XsdValidator::get_schema() noexcept { return pimpl_->schema; } -const XsdSchema* XsdValidator::get_schema() const +const XsdSchema* XsdValidator::get_schema() const noexcept { return pimpl_->schema; } -XsdValidator::operator const void*() const +XsdValidator::operator bool() const noexcept { - return reinterpret_cast(pimpl_->schema && pimpl_->schema->cobj()); + return pimpl_->schema && pimpl_->schema->cobj(); } -void XsdValidator::initialize_valid() +void XsdValidator::initialize_context() { - xmlSchemaSetValidErrors(pimpl_->context, &callback_validity_error, &callback_validity_warning, this); - SchemaValidatorBase::initialize_valid(); + xmlSchemaSetValidErrors(pimpl_->context, get_callback_validity_error_cfunc(), + get_callback_validity_warning_cfunc(), this); + SchemaValidatorBase::initialize_context(); } void XsdValidator::validate(const Document* document) { if (!document) - throw internal_error("XsdValidator::validate(): document must not be 0."); + throw internal_error("XsdValidator::validate(): document must not be nullptr."); if (!*this) throw internal_error("XsdValidator::validate(): Must have a schema to validate document"); @@ -143,7 +144,7 @@ void XsdValidator::validate(const Document* document) throw internal_error("XsdValidator::validate(): Could not create validating context"); xmlResetLastError(); - initialize_valid(); + initialize_context(); const int res = xmlSchemaValidateDoc(pimpl_->context, const_cast(document->cobj())); if (res != 0) @@ -152,12 +153,12 @@ void XsdValidator::validate(const Document* document) auto error_str = format_xml_error(); if (error_str.empty()) - error_str = "Error code from xmlSchemaValidateDoc(): " + Glib::ustring::format(res); + error_str = "Error code from xmlSchemaValidateDoc(): " + std::to_string(res); throw validity_error("Document failed XSD schema validation.\n" + error_str); } } -void XsdValidator::validate(const Glib::ustring& filename) +void XsdValidator::validate(const std::string& filename) { if (!*this) throw internal_error("XsdValidator::validate(): Must have a schema to validate file."); @@ -170,7 +171,7 @@ void XsdValidator::validate(const Glib::ustring& filename) throw internal_error("XsdValidator::validate(): Could not create validating context"); xmlResetLastError(); - initialize_valid(); + initialize_context(); const int res = xmlSchemaValidateFile(pimpl_->context, filename.c_str(), 0); if (res != 0) @@ -179,7 +180,7 @@ void XsdValidator::validate(const Glib::ustring& filename) auto error_str = format_xml_error(); if (error_str.empty()) - error_str = "Error code from xmlSchemaValidateFile(): " + Glib::ustring::format(res); + error_str = "Error code from xmlSchemaValidateFile(): " + std::to_string(res); throw validity_error("XML file failed XSD schema validation.\n" + error_str); } } diff --git a/libxml++/validators/xsdvalidator.h b/libxml++/validators/xsdvalidator.h index 2f14cb09..47c55369 100644 --- a/libxml++/validators/xsdvalidator.h +++ b/libxml++/validators/xsdvalidator.h @@ -20,12 +20,7 @@ #define __LIBXMLPP_VALIDATOR_XSDVALIDATOR_H #include -#include // std::auto_ptr - -namespace Glib -{ -class ustring; -} +#include // std::unique_ptr namespace xmlpp { @@ -40,18 +35,20 @@ class XsdSchema; class XsdValidator : public SchemaValidatorBase { public: - XsdValidator(); + LIBXMLPP_API XsdValidator(); /** Create a validator and parse a schema definition file. * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - explicit XsdValidator(const Glib::ustring& filename); + LIBXMLPP_API + explicit XsdValidator(const std::string& filename); /** Create a validator and parse a schema definition document. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API explicit XsdValidator(const Document* document); /** Create a validator. @@ -63,20 +60,20 @@ class XsdValidator : public SchemaValidatorBase * validator keeps a pointer to it. The caller is responsible for * deleting the schema when it's no longer needed. */ + LIBXMLPP_API explicit XsdValidator(XsdSchema* schema, bool take_ownership); + LIBXMLPP_API ~XsdValidator() override; - //TODO: Remove virtuals when we can break ABI, - //or really put these in the base class. - /** Parse a schema definition file. * If the validator already contains a schema, that schema is released * (deleted if the validator owns the schema). * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - virtual void parse_file(const Glib::ustring& filename); + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse a schema definition from a string. * If the validator already contains a schema, that schema is released @@ -84,7 +81,8 @@ class XsdValidator : public SchemaValidatorBase * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - virtual void parse_memory(const Glib::ustring& contents); + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse a schema definition from a document. * If the validator already contains a schema, that schema is released @@ -92,7 +90,8 @@ class XsdValidator : public SchemaValidatorBase * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ - virtual void parse_document(const Document* document); + LIBXMLPP_API + void parse_document(const Document* document) override; /** Set a schema. * If the validator already contains a schema, that schema is released @@ -105,6 +104,7 @@ class XsdValidator : public SchemaValidatorBase * validator keeps a pointer to it. The caller is responsible for * deleting the schema when it's no longer needed. */ + LIBXMLPP_API void set_schema(XsdSchema* schema, bool take_ownership); /** Test whether a schema has been parsed. @@ -114,39 +114,46 @@ class XsdValidator : public SchemaValidatorBase * do_something(); * @endcode */ - virtual operator BoolExpr() const; + LIBXMLPP_API + explicit operator bool() const noexcept override; /** Get the schema. - * @returns A pointer to the schema, or 0. + * @returns A pointer to the schema, or nullptr. */ - XsdSchema* get_schema(); + LIBXMLPP_API + XsdSchema* get_schema() noexcept; /** Get the schema. - * @returns A pointer to the schema, or 0. + * @returns A pointer to the schema, or nullptr. */ - const XsdSchema* get_schema() const; + LIBXMLPP_API + const XsdSchema* get_schema() const noexcept; /** Validate a document, using a previously parsed schema. * @param document Pointer to the document. * @throws xmlpp::internal_error * @throws xmlpp::validity_error */ - virtual void validate(const Document* document); + LIBXMLPP_API + void validate(const Document* document) override; /** Validate an XML file, using a previously parsed schema. * @param filename The URL of the XML file. * @throws xmlpp::internal_error * @throws xmlpp::validity_error */ - virtual void validate(const Glib::ustring& filename); + LIBXMLPP_API + void validate(const std::string& filename) override; protected: - void initialize_valid() override; + LIBXMLPP_API + void initialize_context() override; + LIBXMLPP_API void release_underlying() override; private: struct Impl; - std::auto_ptr pimpl_; + std::unique_ptr pimpl_; }; } // namespace xmlpp diff --git a/libxml++/xsdschema.cc b/libxml++/xsdschema.cc index 94a92384..9368fbe9 100644 --- a/libxml++/xsdschema.cc +++ b/libxml++/xsdschema.cc @@ -29,7 +29,7 @@ namespace class XsdSchemaParserContextHolder { public: - XsdSchemaParserContextHolder(xmlSchemaParserCtxtPtr ctx): ctx_(ctx) {} + explicit XsdSchemaParserContextHolder(xmlSchemaParserCtxtPtr ctx) noexcept : ctx_(ctx) {} ~XsdSchemaParserContextHolder() { if (ctx_) xmlSchemaFreeParserCtxt(ctx_); } private: @@ -42,13 +42,13 @@ namespace xmlpp struct XsdSchema::Impl { - Impl() : schema(nullptr), document(nullptr) {} + Impl() noexcept : schema(nullptr), document(nullptr) {} _xmlSchema* schema; _xmlDoc* document; }; - + XsdSchema::XsdSchema() : pimpl_(new Impl) { @@ -60,7 +60,7 @@ XsdSchema::XsdSchema(_xmlSchema* schema) pimpl_->schema = schema; } -XsdSchema::XsdSchema(const Glib::ustring& filename) +XsdSchema::XsdSchema(const std::string& filename) : pimpl_(new Impl) { parse_file(filename); @@ -77,24 +77,24 @@ XsdSchema::~XsdSchema() release_underlying(); } -void XsdSchema::parse_file(const Glib::ustring& filename) +void XsdSchema::parse_file(const std::string& filename) { xmlResetLastError(); release_underlying(); parse_context(xmlSchemaNewParserCtxt(filename.c_str())); } -void XsdSchema::parse_memory(const Glib::ustring& contents) +void XsdSchema::parse_memory(const ustring& contents) { xmlResetLastError(); release_underlying(); - parse_context(xmlSchemaNewMemParserCtxt(contents.c_str(), contents.bytes())); + parse_context(xmlSchemaNewMemParserCtxt(contents.c_str(), contents.size())); } void XsdSchema::parse_document(const Document* document) { if (!document) - throw parse_error("XsdSchema::parse_document(): document must not be 0."); + throw parse_error("XsdSchema::parse_document(): document must not be nullptr."); xmlResetLastError(); release_underlying(); @@ -111,7 +111,7 @@ void XsdSchema::parse_context(_xmlSchemaParserCtxt* context) { if (!context) throw parse_error("XsdSchema::parse_context(): Could not create parser context.\n" + format_xml_error()); - + XsdSchemaParserContextHolder holder(context); pimpl_->schema = xmlSchemaParse(context); @@ -122,12 +122,12 @@ void XsdSchema::parse_context(_xmlSchemaParserCtxt* context) } } -_xmlSchema* XsdSchema::cobj() +_xmlSchema* XsdSchema::cobj() noexcept { return pimpl_->schema; } -const _xmlSchema* XsdSchema::cobj() const +const _xmlSchema* XsdSchema::cobj() const noexcept { return pimpl_->schema; } diff --git a/libxml++/xsdschema.h b/libxml++/xsdschema.h index 13330257..a82123a2 100644 --- a/libxml++/xsdschema.h +++ b/libxml++/xsdschema.h @@ -21,7 +21,7 @@ #include #include -#include // std::auto_ptr +#include // std::unique_ptr #ifndef DOXYGEN_SHOULD_SKIP_THIS extern "C" { @@ -41,62 +41,70 @@ namespace xmlpp class XsdSchema : public SchemaBase { public: - XsdSchema(); + LIBXMLPP_API XsdSchema(); /** Create a schema from the underlying libxml schema element. * @param schema A pointer to the libxml schema element. The XsdSchema takes * ownership of the _xmlSchema. The caller must not deallocate it. */ + LIBXMLPP_API explicit XsdSchema(_xmlSchema* schema); /** Create a schema from a schema definition file. * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - explicit XsdSchema(const Glib::ustring& filename); + LIBXMLPP_API + explicit XsdSchema(const std::string& filename); /** Create a schema from an XML document. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API explicit XsdSchema(const Document* document); - ~XsdSchema() override; + LIBXMLPP_API ~XsdSchema() override; /** Parse a schema definition file. * If another schema has been parsed before, that schema is replaced by the new one. * @param filename The URL of the schema. * @throws xmlpp::parse_error */ - void parse_file(const Glib::ustring& filename) override; + LIBXMLPP_API + void parse_file(const std::string& filename) override; /** Parse a schema definition from a string. * If another schema has been parsed before, that schema is replaced by the new one. * @param contents The schema definition as a string. * @throws xmlpp::parse_error */ - void parse_memory(const Glib::ustring& contents) override; + LIBXMLPP_API + void parse_memory(const ustring& contents) override; /** Parse a schema definition from a document. * If another schema has been parsed before, that schema is replaced by the new one. * @param document A preparsed document tree, containing the schema definition. * @throws xmlpp::parse_error */ + LIBXMLPP_API void parse_document(const Document* document) override; /** Access the underlying libxml implementation. */ - _xmlSchema* cobj(); + LIBXMLPP_API _xmlSchema* cobj() noexcept; /** Access the underlying libxml implementation. */ - const _xmlSchema* cobj() const; + LIBXMLPP_API const _xmlSchema* cobj() const noexcept; protected: + LIBXMLPP_API void release_underlying(); + LIBXMLPP_API void parse_context(_xmlSchemaParserCtxt* context); private: struct Impl; - std::auto_ptr pimpl_; + std::unique_ptr pimpl_; }; } // namespace xmlpp diff --git a/libxml++config.h.in b/libxml++config.h.in index fa360735..f37f78a1 100755 --- a/libxml++config.h.in +++ b/libxml++config.h.in @@ -1,13 +1,11 @@ #ifndef _LIBXMLPP_CONFIG_H #define _LIBXMLPP_CONFIG_H -#include - /* Define to omit deprecated API from the library. */ #undef LIBXMLXX_DISABLE_DEPRECATED -/* This is always set. This is only for backwards compatibility. */ -#undef LIBXMLCPP_EXCEPTIONS_ENABLED +/* Defined if the C++ library supports std::exception_ptr. */ +#undef LIBXMLXX_HAVE_EXCEPTION_PTR /* Major version number of libxml++. */ #undef LIBXMLXX_MAJOR_VERSION @@ -18,19 +16,34 @@ /* Micro version number of libxml++. */ #undef LIBXMLXX_MICRO_VERSION -#ifdef GLIBMM_DLL - #if defined(LIBXMLPP_BUILD) && defined(_WINDLL) - // Do not dllexport as it is handled by gendef on MSVC - #define LIBXMLPP_API - #elif !defined(LIBXMLPP_BUILD) +// Enable DLL-specific stuff only when not building a static library +#if !defined(__CYGWIN__) && (defined(__MINGW32__) || defined(_MSC_VER)) && !defined(LIBXMLXX_STATIC) +# define LIBXMLPP_DLL 1 +#endif + +#ifdef LIBXMLPP_DLL + #ifdef LIBXMLPP_BUILD + #define LIBXMLPP_API __declspec(dllexport) + #ifdef __GNUC__ + #define LIBXMLPP_VISIBILITY_DEFAULT LIBXMLPP_API __attribute__((visibility("default"))) + #define LIBXMLPP_MEMBER_METHOD + #endif + #elif !defined (__GNUC__) #define LIBXMLPP_API __declspec(dllimport) - #else - /* Build a static library */ + #else /* don't dllimport classes/methods on GCC/MinGW */ #define LIBXMLPP_API - #endif /* LIBXMLPP_BUILD - _WINDLL */ + #endif /* LIBXMLPP_BUILD - DLL */ #else + /* Build a static library or a non-Windows library*/ #define LIBXMLPP_API #endif /* GLIBMM_DLL */ +#ifndef LIBXMLPP_VISIBILITY_DEFAULT + #define LIBXMLPP_VISIBILITY_DEFAULT +#endif +#ifndef LIBXMLPP_MEMBER_METHOD + #define LIBXMLPP_MEMBER_METHOD LIBXMLPP_API +#endif + #endif /* _LIBXMLPP_CONFIG_H */ diff --git a/libxml++config.h.meson b/libxml++config.h.meson new file mode 100755 index 00000000..2d0d9973 --- /dev/null +++ b/libxml++config.h.meson @@ -0,0 +1,51 @@ +#ifndef _LIBXMLPP_CONFIG_H +#define _LIBXMLPP_CONFIG_H + +/* Define to omit deprecated API from the library. */ +#mesondefine LIBXMLXX_DISABLE_DEPRECATED + +/* Defined if the C++ library supports std::exception_ptr. */ +#mesondefine LIBXMLXX_HAVE_EXCEPTION_PTR + +/* Major version number of libxml++. */ +#mesondefine LIBXMLXX_MAJOR_VERSION + +/* Minor version number of libxml++. */ +#mesondefine LIBXMLXX_MINOR_VERSION + +/* Micro version number of libxml++. */ +#mesondefine LIBXMLXX_MICRO_VERSION + +#mesondefine LIBXMLXX_STATIC + +// Enable DLL-specific stuff only when not building a static library +#if !defined(__CYGWIN__) && (defined(__MINGW32__) || defined(_MSC_VER)) && !defined(LIBXMLXX_STATIC) +# define LIBXMLPP_DLL 1 +#endif + +#ifdef LIBXMLPP_DLL + #ifdef LIBXMLPP_BUILD + #define LIBXMLPP_API __declspec(dllexport) + #ifdef __GNUC__ + #define LIBXMLPP_VISIBILITY_DEFAULT LIBXMLPP_API __attribute__((visibility("default"))) + #define LIBXMLPP_MEMBER_METHOD + #endif + #elif !defined (__GNUC__) + #define LIBXMLPP_API __declspec(dllimport) + #else /* don't dllimport classes/methods on GCC/MinGW */ + #define LIBXMLPP_API + #endif /* LIBXMLPP_BUILD - DLL */ +#else + /* Build a static library or a non-Windows library*/ + #define LIBXMLPP_API +#endif /* GLIBMM_DLL */ + +#ifndef LIBXMLPP_VISIBILITY_DEFAULT + #define LIBXMLPP_VISIBILITY_DEFAULT +#endif +#ifndef LIBXMLPP_MEMBER_METHOD + #define LIBXMLPP_MEMBER_METHOD LIBXMLPP_API +#endif + +#endif /* _LIBXMLPP_CONFIG_H */ + diff --git a/libxml++.doap b/libxmlplusplus.doap similarity index 53% rename from libxml++.doap rename to libxmlplusplus.doap index 155c05f6..88f82ee0 100644 --- a/libxml++.doap +++ b/libxmlplusplus.doap @@ -1,21 +1,26 @@ + - libxml++ + + libxmlplusplus C++ bindings for libxml2 - libxml++ is a C++ wrapper for the libxml2 XML parser library. + +libxmlplusplus (aka libxml++) is a C++ wrapper for the libxml2 XML parser library. It has SAX and DOM-like APIs, but does not attempt to conform exactly to -the DOM specification. Its API is simpler than the underlying libxml2 C API. - - +the DOM specification. Its API is simpler than the underlying libxml2 C API. + + + - - C++ @@ -27,9 +32,9 @@ the DOM specification. Its API is simpler than the underlying libxml2 C API. - Christophe de Vienne - - cdevienn + Kjell Ahlstedt + + kjellahl diff --git a/meson.build b/meson.build new file mode 100644 index 00000000..b7f31e55 --- /dev/null +++ b/meson.build @@ -0,0 +1,419 @@ +# This file is part of libxml++. + +project('libxml++', 'cpp', + version: '5.4.0', + license: 'LGPLv2.1+', + default_options: [ + 'warning_level=1', + 'cpp_std=c++17', + ], + meson_version: '>= 0.62.0', # required for variables in pkgconfig.generate() +) + +xmlxx_api_version = '5.0' +xmlxx_pcname = meson.project_name() + '-' + xmlxx_api_version + +xmlxx_version_array = meson.project_version().split('.') +xmlxx_major_version = xmlxx_version_array[0].to_int() +xmlxx_minor_version = xmlxx_version_array[1].to_int() +xmlxx_micro_version = xmlxx_version_array[2].to_int() + +# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html +# The relation between libtool's current:revison:age interface versioning +# and the .so filename, .so.x.y.z, is +# x = current - age +# y = age +# z = revision +# If libtool_soversion is updated as described in libtool's documentation, +# x.y.z will usually *not* be equal to meson.project_version(). +libtool_soversion = [1, 0, 0] +xmlxx_libversion = '@0@.@1@.@2@'.format( + libtool_soversion[0] - libtool_soversion[2], + libtool_soversion[2], + libtool_soversion[1] +) +macos_darwin_versions = [ + libtool_soversion[0] + 1, + '@0@.@1@'.format(libtool_soversion[0] + 1, libtool_soversion[1]) +] + +# Source and build root directories of the current (sub)project. +project_source_root = meson.project_source_root() +project_build_root = meson.project_build_root() + +cpp_compiler = meson.get_compiler('cpp') +is_msvc = cpp_compiler.get_id() == 'msvc' + +python3 = find_program('python3', version: '>=3.7') + +# Do we build from a git repository? +# Suppose we do if and only if the meson.build file is tracked by git. +cmd_py = ''' +import shutil, subprocess, sys +git_exe = shutil.which('git') +if not git_exe: + sys.exit(1) +cmd = [ git_exe, 'ls-files', '--error-unmatch', 'meson.build' ] +sys.exit(subprocess.run(cmd, cwd=sys.argv[1], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode) +''' +is_git_build = run_command( + python3, '-c', cmd_py, + project_source_root, + check: false, +).returncode() == 0 + +# Are we testing a dist tarball while it's being built? +# There ought to be a better way. https://github.com/mesonbuild/meson/issues/6866 +is_dist_check = project_source_root.contains('dist-unpack') and \ + project_build_root.contains('dist-build') + +# Options. +maintainer_mode_opt = get_option('maintainer-mode') +maintainer_mode = maintainer_mode_opt == 'true' or \ + (maintainer_mode_opt == 'if-git-build' and is_git_build) +if is_dist_check + message('Looks like a tarball is being tested. ' + \ + 'Option "dist-warnings" is used instead of "warnings".') + cpp_warnings = get_option('dist-warnings') +else + cpp_warnings = get_option('warnings') +endif +if get_option('warning_level') in ['0','1','2','3','4','5'] + warning_level = get_option('warning_level').to_int() +else + # For instance get_option('warning_level') == 'everything' + warning_level = 99 +endif +werror = get_option('werror') +build_deprecated_api = get_option('build-deprecated-api') +build_documentation_opt = get_option('build-documentation') +build_documentation = build_documentation_opt == 'true' or \ + (build_documentation_opt == 'if-maintainer-mode' and maintainer_mode) +build_examples = get_option('build-examples') +build_tests = get_option('build-tests') +use_msvc14x_toolset_ver = get_option('msvc14x-parallel-installable') + +# Installation directories are relative to {prefix}. +install_prefix = get_option('prefix') +install_includedir = get_option('includedir') +install_libdir = get_option('libdir') +install_datadir = get_option('datadir') +install_pkgconfigdir = install_libdir / 'pkgconfig' + +# Dependencies. +# xmlxx_build_dep: Dependencies when building the libxml++ library. +# xmlxx_dep (created in libxml++/meson.build): +# Dependencies when using the libxml++ library. + +xml2_min_ver = '2.7.7' +xml2_req = '>= @0@'.format(xml2_min_ver) +xml2_dep = dependency( + ['libxml-2.0', 'LibXml2'], + version: xml2_req, + fallback: ['libxml2'] +) + +xmlxx_pc_requires = [] +libxml2_lib_pkgconfig = [] + +# Put libxml-2.0 in the 'Requires:' section in the generated pkg-config file if +# we found it by pkg-config +if xml2_dep.type_name() == 'pkgconfig' or xml2_dep.type_name() == 'internal' + xmlxx_pc_requires += ['libxml-2.0' + xml2_req] +else + libxml2_lib_pkgconfig += [xml2_dep.get_variable( + cmake: 'LIBXML2_LIBRARIES', + default_value: 'LibXml2.lib', + )] +endif + +# Make sure we link to libxml-2.0 +xmlxx_build_dep = [xml2_dep] + +# Some dependencies are required only in maintainer mode and/or if +# reference documentation shall be built. +mm_common_get = find_program('mm-common-get', required: false) +if maintainer_mode and not mm_common_get.found() + message('Maintainer mode requires the \'mm-common-get\' command. If it is not found,\n' + + 'use \'-Dmaintainer-mode=false\' or install the \'mm-common\' package, version 1.0.0 or higher.') + # If meson --wrap-mode != forcefallback, Meson falls back to the mm-common + # subproject only if mm-common-get is required. + mm_common_get = find_program('mm-common-get', required: true) +endif +doxygen = find_program('doxygen', required: build_documentation) +dot = find_program('dot', required: false) # Used by Doxygen, if found +xsltproc = find_program('xsltproc', required: build_documentation) + +if build_documentation and not dot.found() + message('The \'dot\' command is not found.\n ' + \ + 'This will affect the look of the inheritance diagrams in the documentation.') +endif + +# Script files copied to 'untracked/' by mm-common-get. +script_dir = project_source_root / 'untracked' / 'build_scripts' +doc_reference_py = script_dir / 'doc-reference.py' +dist_changelog_py = script_dir / 'dist-changelog.py' +dist_build_scripts_py = script_dir / 'dist-build-scripts.py' + +# xmlxx's own script files. +xmlxx_script_dir = project_source_root / 'tools' / 'build_scripts' +tutorial_custom_cmd_py = xmlxx_script_dir / 'tutorial-custom-cmd.py' + +if maintainer_mode + # Copy files to untracked/build_scripts and untracked/docs. + run_command(mm_common_get, '--force', script_dir, + project_source_root / 'untracked' / 'docs', + check: true, + ) +elif not import('fs').is_file(doc_reference_py) + warning('Missing files in untracked/.\n ' + \ + 'Enable maintainer-mode if you want to build documentation or create a dist tarball.') +endif + +# Check if perl is required and available. +doc_perl_prop = run_command( + python3, doc_reference_py, 'get_script_property', + '', # MMDOCTOOLDIR is not used + 'requires_perl', + check: false, +) +if not (doc_perl_prop.returncode() == 0 and doc_perl_prop.stdout() == 'false') + # Perl is required, if documentation shall be built. + perl = find_program('perl', required: build_documentation) +endif + +# Add toolset version in builds done with Visual Studio 2017 or later +msvc14x_toolset_ver = '' + +if is_msvc + if use_msvc14x_toolset_ver + if cpp_compiler.version().version_compare('>=19.30') + msvc14x_toolset_ver = '-vc143' + elif cpp_compiler.version().version_compare('>=19.20') + msvc14x_toolset_ver = '-vc142' + elif cpp_compiler.version().version_compare('>=19.10') + msvc14x_toolset_ver = '-vc141' + endif + endif +endif + +xmlxx_libname = 'xml++' + msvc14x_toolset_ver + '-' + xmlxx_api_version + +# Set compiler warnings. +# Meson warns if any of the /W1, /W2, /W3, /W4, /Wall, -Wall, -Wextra, -Werror +# compiler options are added with add_project_arguments(). +# Avoid such warnings, when possible. +# See _warn_about_builtin_args() in meson/mesonbuild/interpreter/interpreter.py. +warning_flags = [] +if cpp_warnings == 'min' + if warning_level == 0 + if is_msvc + warning_flags = ['/W2'] + else + warning_flags = ['-Wall'] + endif + endif +elif cpp_warnings == 'max' or cpp_warnings == 'fatal' + if warning_level < 3 + if is_msvc + warning_flags = ['/W4'] + else + warning_flags = ['-pedantic', '-Wall', '-Wextra'] + endif + endif + if not is_msvc + warning_flags += '-Wformat-security -Wsuggest-override -Wshadow -Wno-long-long'.split() + endif + if cpp_warnings == 'fatal' and not werror + if is_msvc + warning_flags += ['/WX'] + else + warning_flags += ['-Werror'] + endif + endif +endif + +warning_flags = cpp_compiler.get_supported_arguments(warning_flags) +add_project_arguments(warning_flags, language: 'cpp') + +# MSVC: Ignore warnings that aren't really harmful, but make those +# that should not be overlooked stand out. +if is_msvc + disable_warnings_list = [ + '/utf-8', # Avoid C4819 unicode conversion warnings when building on CJK locales + '/wd4706', # assignment within conditional expression + ] + + # Turn off harmless warnings but make potentially dangerous ones glaring, + # distributed with GLib, if available + use_recommended_pragmas = cpp_compiler.get_supported_arguments('/FImsvc_recommended_pragmas.h') + if use_recommended_pragmas.length() > 0 + add_project_arguments(use_recommended_pragmas, language: 'cpp') + else + disable_warnings_list += [ + '/wd4244', # 'conversion' conversion from 'type1' to 'type2', possible loss of data + '/wd4101', # unreferenced local variable + ] + endif + + if host_machine.cpu_family() == 'x86_64' or host_machine.cpu_family() == 'aarch64' + # 'var' : conversion from 'size_t' to 'type', possible loss of data (applies on 64-bit builds) + disable_warnings_list += '/wd4267' + endif + add_project_arguments( + cpp_compiler.get_supported_arguments(disable_warnings_list), + language: 'cpp' + ) +endif + +# Configure files +pkg_conf_data = configuration_data() +pkg_conf_data.set('PACKAGE_NAME', meson.project_name()) # MSVC_NMake/libxml++/libxml++.rc +pkg_conf_data.set('PACKAGE_VERSION', meson.project_version()) + +if not build_deprecated_api + pkg_conf_data.set('LIBXMLXX_DISABLE_DEPRECATED', 1) +endif +pkg_conf_data.set('LIBXMLXX_MAJOR_VERSION', xmlxx_major_version) +pkg_conf_data.set('LIBXMLXX_MINOR_VERSION', xmlxx_minor_version) +pkg_conf_data.set('LIBXMLXX_MICRO_VERSION', xmlxx_micro_version) + +# Configuration test +if cpp_compiler.compiles(files('tools' / 'conf_tests' / 'have_exception_ptr.cc')) + pkg_conf_data.set('LIBXMLXX_HAVE_EXCEPTION_PTR', 1) +endif + +# Static library? +library_build_type = get_option('default_library') +pkg_conf_data.set('LIBXMLXX_STATIC', library_build_type == 'static') + + +if cpp_compiler.get_argument_syntax() == 'msvc' + if library_build_type == 'both' + error('Dynamic+Static builds are not supported by MSVC-style builds') + endif +endif + +xmlxxconfig_h_meson = files('libxml++config.h.meson') +install_includeconfigdir = install_libdir / xmlxx_pcname / 'include' +configure_file( + input: xmlxxconfig_h_meson, + output: 'libxml++config.h', + configuration: pkg_conf_data, + install: true, + install_dir: install_includeconfigdir, + install_tag: 'devel', +) + +subdir('MSVC_NMake/libxml++') +subdir('libxml++') +subdir('examples') +subdir('tests') +subdir('docs/reference') +subdir('docs/manual') + +# Add a ChangeLog file to the distribution directory. +meson.add_dist_script( + python3, dist_changelog_py, + project_source_root, +) + +# Don't distribute these files and directories. +dont_distribute = [ + 'libxmlplusplus.doap', + '.github', +] +# Add build scripts to the distribution directory, and delete .gitignore +# files and an empty $MESON_PROJECT_DIST_ROOT/build/ directory. +meson.add_dist_script( + python3, dist_build_scripts_py, + project_source_root, + 'untracked' / 'build_scripts', + dont_distribute, +) + +if meson.is_subproject() + pkgconfig_vars = { + 'htmlrefdir': install_prefix / install_docdir / 'reference' / 'html', + 'htmlrefpub': 'https://libxmlplusplus.github.io/libxmlplusplus/reference/html/' + } + if build_documentation + pkgconfig_vars += {'doxytagfile': tag_file.full_path()} + # May be used in a main project. + global_tag_file_target = tag_file + endif + xmlxx_dep = declare_dependency( + dependencies: xmlxx_own_dep, + variables: pkgconfig_vars, + ) + + # A main project that looks for xmlxx_pcname.pc shall find xmlxx_dep. + meson.override_dependency(xmlxx_pcname, xmlxx_dep) +endif + +# Print a summary. +real_maintainer_mode = '' +if maintainer_mode_opt == 'if-git-build' + real_maintainer_mode = ' (@0@)'.format(maintainer_mode) +endif + +real_build_documentation = '' +if build_documentation_opt == 'if-maintainer-mode' + real_build_documentation = ' (@0@)'.format(build_documentation) +endif + +explain_man = '' +if build_manual_opt and not build_manual + explain_man = ' (requires that documentation is built)' +endif + +validate = get_option('validation') and can_parse_and_validate and build_manual +explain_val = '' +if get_option('validation') and not validate + if not build_manual + explain_val = ' (requires that the tutorial is built)' + else + explain_val = ' (requires xmllint with Relax NG and DocBook V5.0 support)' + endif +endif + +build_pdf = build_pdf_by_default and can_build_pdf and build_manual +explain_pdf = '' +if build_pdf_by_default and not build_pdf + if not build_manual + explain_pdf = ' (requires that the tutorial is built)' + else + explain_pdf = ' (requires dblatex or (xsltproc and fop))' + endif +endif + +summary = [ + '', + '------', + meson.project_name() + ' ' + meson.project_version(), + '', + ' Maintainer mode: @0@@1@'.format(maintainer_mode_opt, real_maintainer_mode), + ' Compiler warnings: @0@ (warning_level: @1@, werror: @2@)'. \ + format(cpp_warnings, warning_level, werror), + ' Build deprecated API: @0@'.format(build_deprecated_api), + 'Build HTML documentation: @0@@1@'.format(build_documentation_opt, real_build_documentation), + ' Build tutorial: @0@@1@'.format(build_manual, explain_man), + ' XML validation: @0@@1@'.format(validate, explain_val), + ' Build PDF: @0@@1@'.format(build_pdf, explain_pdf), + ' Build example programs: @0@'.format(build_examples), + ' Build test programs: @0@'.format(build_tests), + 'Directories:', + ' prefix: @0@'.format(install_prefix), + ' includedir: @0@'.format(install_prefix / install_includedir), + ' includexmlxxdir: @0@'.format(install_prefix / install_includedir / xmlxx_pcname), + ' libdir: @0@'.format(install_prefix / install_libdir), + ' includeconfigdir: @0@'.format(install_prefix / install_includeconfigdir), + ' pkgconfigdir: @0@'.format(install_prefix / install_pkgconfigdir), + ' datadir: @0@'.format(install_prefix / install_datadir), + ' docdir: @0@'.format(install_prefix / install_docdir), + ' devhelpdir: @0@'.format(install_prefix / install_devhelpdir), + ' tutorialdir: @0@'.format(install_prefix / install_tutorialdir), + '------', +] + +message('\n'.join(summary)) diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 00000000..f362d77b --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,22 @@ +option('maintainer-mode', type: 'combo', choices: ['false', 'if-git-build', 'true'], + value: 'if-git-build', description: 'Let mm-common-get copy some files to untracked/') +option('warnings', type: 'combo', choices: ['no', 'min', 'max', 'fatal'], + value: 'min', description: 'Compiler warning level') +option('dist-warnings', type: 'combo', choices: ['no', 'min', 'max', 'fatal'], + value: 'fatal', description: 'Compiler warning level when a tarball is created') +option('build-deprecated-api', type: 'boolean', value: true, + description: 'Build deprecated API and include it in the library') +option('build-documentation', type: 'combo', choices: ['false', 'if-maintainer-mode', 'true'], + value: 'if-maintainer-mode', description: 'Build and install the documentation') +option('build-manual', type: 'boolean', value: true, + description: 'Build tutorial HTML files, if documentation is built') +option('validation', type: 'boolean', value: true, + description: 'Validate the tutorial XML file, if tutorial HTML files are built') +option('build-pdf', type: 'boolean', value: false, + description: 'Build tutorial PDF file, if tutorial HTML files are built') +option('build-examples', type: 'boolean', value: true, + description: 'Build example programs') +option('build-tests', type: 'boolean', value: true, + description: 'Build test programs') +option('msvc14x-parallel-installable', type: 'boolean', value: true, + description: 'Use separate DLL and LIB filenames for Visual Studio 2017 and 2019') diff --git a/mingw-cross-file.txt b/mingw-cross-file.txt new file mode 100644 index 00000000..342ebe55 --- /dev/null +++ b/mingw-cross-file.txt @@ -0,0 +1,23 @@ +# Cross compiling with MinGW, Linux -> Windows +# meson --cross-file mingw-cross-file.txt ..... + +[constants] +prefix = 'x86_64-w64-mingw32-' + +[binaries] +c = prefix + 'gcc' +cpp = prefix + 'g++' +ar = prefix + 'ar' +strip = prefix + 'strip' +windres = prefix + 'windres' +exe_wrapper = 'wine64' + +[host_machine] +system = 'windows' +cpu_family = 'x86_64' +cpu = 'x86_64' +endian = 'little' + +[cmake] +CMAKE_C_COMPILER = prefix + 'gcc' +CMAKE_CXX_COMPILER = prefix + 'g++' diff --git a/subprojects/libxml2.wrap b/subprojects/libxml2.wrap new file mode 100644 index 00000000..9c0e5f6d --- /dev/null +++ b/subprojects/libxml2.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://gitlab.gnome.org/GNOME/libxml2.git +revision = master +depth = 1 + +[provide] +dependency_names = libxml-2.0 diff --git a/subprojects/mm-common.wrap b/subprojects/mm-common.wrap new file mode 100644 index 00000000..296109fa --- /dev/null +++ b/subprojects/mm-common.wrap @@ -0,0 +1,9 @@ +[wrap-git] +directory=mm-common +url=https://gitlab.gnome.org/GNOME/mm-common.git +revision=master +depth=1 + +[provide] +dependency_names = mm-common-libstdc++ +program_names = mm-common-get diff --git a/tests/Makefile.am b/tests/Makefile.am index 96bfe237..734ca14b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,8 +11,7 @@ ## Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public -## License along with this library; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +## License along with this library; if not, see . AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I. $(LIBXMLXX_CFLAGS) AM_CXXFLAGS = $(LIBXMLXX_WXXFLAGS) @@ -21,10 +20,12 @@ LDADD = $(top_builddir)/libxml++/libxml++-$(LIBXMLXX_API_VERSION).la $(LIBXMLXX_ check_PROGRAMS = \ saxparser_chunk_parsing_inconsistent_state/test \ saxparser_parse_double_free/test \ - saxparser_parse_stream_inconsistent_state/test + saxparser_parse_stream_inconsistent_state/test \ + istream_ioparser/test TESTS = $(check_PROGRAMS) saxparser_chunk_parsing_inconsistent_state_test_SOURCES = saxparser_chunk_parsing_inconsistent_state/main.cc saxparser_parse_double_free_test_SOURCES = saxparser_parse_double_free/main.cc saxparser_parse_stream_inconsistent_state_test_SOURCES = saxparser_parse_stream_inconsistent_state/main.cc +istream_ioparser_test_SOURCES = istream_ioparser/main.cc diff --git a/tests/istream_ioparser/main.cc b/tests/istream_ioparser/main.cc new file mode 100644 index 00000000..61f5833c --- /dev/null +++ b/tests/istream_ioparser/main.cc @@ -0,0 +1,152 @@ +/* Copyright (C) 2022 The libxml++ development team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include + +#include +#include +#include +#include +#include + +class test_streambuf : public std::streambuf +{ +public: + test_streambuf() : + uflow_calls(0), + underflow_calls(0), + ofs(0), + buf("\n") + { + } + +protected: + /* Simulate some kind of streambuf impl that doesn't setg() */ + int_type underflow() override + { + ++underflow_calls; + if (ofs >= (sizeof(buf)-1)) + return traits_type::eof(); + return traits_type::to_int_type(buf[ofs]); + } + + int_type uflow() override + { + ++uflow_calls; + if (ofs >= (sizeof(buf)-1)) + return traits_type::eof(); + return traits_type::to_int_type(buf[ofs++]); + } + + std::streamsize showmanyc() override + { + if (ofs >= (sizeof(buf)-1)) + return traits_type::eof(); + return sizeof(buf)-1-ofs; + } + + std::streamsize xsgetn(char_type* s, std::streamsize count) override + { + auto n = std::min(count, static_cast(sizeof(buf)-1-ofs)); + memcpy(s, buf + ofs, n); + ofs += n; + return n; + } + +public: + int uflow_calls; + int underflow_calls; + +private: + size_t ofs; + char buf[15]; +}; + +class MySaxParser : public xmlpp::SaxParser { +public: + bool saw_root = false; +protected: + void on_start_document() override + { + saw_root = false; + } + void on_end_element(const xmlpp::ustring &name) override + { + if (name == "root") + saw_root = true; + } +}; + +int main() +{ + { // Check DomParser works well with normal and custom istreams + xmlpp::DomParser parser; + try + { + std::stringstream ss(""); + parser.parse_stream(ss); + } + catch(...) + { + assert(false); + } + + { + auto doc = parser.get_document(); + assert(doc->get_root_node()->get_name2() == "root"); + } + + { + test_streambuf buf; + try { + std::istream is(&buf); + parser.parse_stream(is); + } catch (...) { + assert(false); + } + assert(buf.underflow_calls + buf.uflow_calls < 3); + auto doc = parser.get_document(); + assert(doc->get_root_node()->get_name2() == "root"); + } + } + { // Check SaxParser works well with normal and custom istreams. + MySaxParser parser; + try + { + std::stringstream ss(""); + parser.parse_stream(ss); + } + catch(...) + { + assert(false); + } + assert(parser.saw_root); + + { + test_streambuf buf; + try { + std::istream is(&buf); + parser.parse_stream(is); + } catch (...) { + assert(false); + } + assert(buf.underflow_calls + buf.uflow_calls < 3); + assert(parser.saw_root); + } + } + assert(true); + return EXIT_SUCCESS; +} diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 00000000..161a6462 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,35 @@ +# tests + +# Input: xmlxx_own_dep, build_tests +# Output: - + +test_programs = [ +# [[dir-name], exe-name, [sources]] + [['istream_ioparser'], 'test', ['main.cc']], + [['saxparser_chunk_parsing_inconsistent_state'], 'test', ['main.cc']], + [['saxparser_parse_double_free'], 'test', ['main.cc']], + [['saxparser_parse_stream_inconsistent_state'], 'test', ['main.cc']], +] + +foreach ex : test_programs + dir = '' + foreach dir_part : ex[0] + dir = dir / dir_part + endforeach + ex_name = (dir / ex[1]).underscorify() + ex_sources = [] + foreach src : ex[2] + ex_sources += dir / src + endforeach + + exe_file = executable(ex_name, ex_sources, + dependencies: xmlxx_own_dep, + implicit_include_directories: false, + build_by_default: build_tests, + install: false, + ) + + if build_tests + test(ex_name, exe_file) + endif +endforeach diff --git a/tests/saxparser_chunk_parsing_inconsistent_state/main.cc b/tests/saxparser_chunk_parsing_inconsistent_state/main.cc index 5e342339..a6ee1787 100644 --- a/tests/saxparser_chunk_parsing_inconsistent_state/main.cc +++ b/tests/saxparser_chunk_parsing_inconsistent_state/main.cc @@ -11,25 +11,28 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ +#include + +#include #include -#include #include #include -#include - class MySaxParser : public xmlpp::SaxParser { +public: + bool throw_on_start_doc = true; + protected: void on_start_document() override { - throw std::runtime_error("some custom runtime exception"); + if (throw_on_start_doc) + throw std::runtime_error("some custom runtime exception"); } - void on_error(const Glib::ustring& /* text */) override + void on_error(const xmlpp::ustring& /* text */) override { throw std::runtime_error("on_error() called"); } @@ -37,28 +40,34 @@ class MySaxParser : public xmlpp::SaxParser int main() { - Glib::init(); - { MySaxParser parser; bool exceptionThrown = false; try { + // Depending on the libxml2 version, MySaxParser::on_start_document() + // may or may not be called before MySaxParser::on_error(). + parser.throw_on_start_doc = false; parser.parse_chunk(""); parser.parse_stream(ss); } @@ -66,14 +75,18 @@ int main() { // An "Attempt to start a second parse while a parse is in progress." parse // error should not have been thrown. - g_assert_not_reached(); + assert(false); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "some custom runtime exception"); + assert(e.what() == xmlpp::ustring("some custom runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } return EXIT_SUCCESS; diff --git a/tests/saxparser_parse_double_free/main.cc b/tests/saxparser_parse_double_free/main.cc index faaf9648..395bf6ed 100644 --- a/tests/saxparser_parse_double_free/main.cc +++ b/tests/saxparser_parse_double_free/main.cc @@ -11,23 +11,21 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ -#include -#include -#include - #include +#include +#include +#include class OnCdataBlockTestParser : public xmlpp::SaxParser { protected: - void on_cdata_block(const Glib::ustring& text) override + void on_cdata_block(const xmlpp::ustring& text) override { - g_assert_cmpstr(text.c_str(), ==, "some CDATA"); + assert(text == xmlpp::ustring("some CDATA")); throw std::runtime_error("on_cdata_block runtime exception"); } }; @@ -40,21 +38,25 @@ void test_on_cdata_block() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_cdata_block runtime exception"); + assert(e.what() == xmlpp::ustring("on_cdata_block runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnCharactersTestParser : public xmlpp::SaxParser { protected: - void on_characters(const Glib::ustring& characters) override + void on_characters(const xmlpp::ustring& characters) override { - g_assert_cmpstr(characters.c_str(), ==, "abc"); + assert(characters == xmlpp::ustring("abc")); throw std::runtime_error("on_characters runtime exception"); } }; @@ -67,21 +69,25 @@ void test_on_characters() { parser.parse_memory("abc"); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_characters runtime exception"); + assert(e.what() == xmlpp::ustring("on_characters runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnCommentTestParser : public xmlpp::SaxParser { protected: - void on_comment(const Glib::ustring& text) override + void on_comment(const xmlpp::ustring& text) override { - g_assert_cmpstr(text.c_str(), ==, "a comment"); + assert(text == xmlpp::ustring("a comment")); throw std::runtime_error("on_comment runtime exception"); } }; @@ -94,12 +100,16 @@ void test_on_comment() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_comment runtime exception"); + assert(e.what() == xmlpp::ustring("on_comment runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } @@ -120,21 +130,25 @@ void test_on_end_document() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_end_document runtime exception"); + assert(e.what() == xmlpp::ustring("on_end_document runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnEndElementTestParser : public xmlpp::SaxParser { protected: - void on_end_element(const Glib::ustring& name) override + void on_end_element(const xmlpp::ustring& name) override { - g_assert_cmpstr(name.c_str(), ==, "a:root"); + assert(name == xmlpp::ustring("a:root")); throw std::runtime_error("on_end_element runtime exception"); } }; @@ -147,24 +161,28 @@ void test_on_end_element() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_end_element runtime exception"); + assert(e.what() == xmlpp::ustring("on_end_element runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnEntityDeclarationTestParser : public xmlpp::SaxParser { protected: - void on_entity_declaration(const Glib::ustring& name, xmlpp::XmlEntityType /* type */, - const Glib::ustring& /* publicId */, const Glib::ustring& /* systemId */, - const Glib::ustring& content) override + void on_entity_declaration(const xmlpp::ustring& name, xmlpp::XmlEntityType /* type */, + const xmlpp::ustring& /* publicId */, const xmlpp::ustring& /* systemId */, + const xmlpp::ustring& content) override { - g_assert_cmpstr(name.c_str(), ==, "number"); - g_assert_cmpstr(content.c_str(), ==, "42"); + assert(name == xmlpp::ustring("number")); + assert(content.c_str() == xmlpp::ustring("42")); throw std::runtime_error("on_entity_declaration runtime exception"); } }; @@ -177,19 +195,23 @@ void test_on_entity_declaration() { parser.parse_memory("]>"); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_entity_declaration runtime exception"); + assert(e.what() == xmlpp::ustring("on_entity_declaration runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnErrorTestParser : public xmlpp::SaxParser { protected: - void on_error(const Glib::ustring& /* text */) override + void on_error(const xmlpp::ustring& /* text */) override { throw std::runtime_error("on_error runtime exception"); } @@ -203,12 +225,16 @@ void test_on_error() { parser.parse_memory("&unknown;"); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_error runtime exception"); + assert(e.what() == xmlpp::ustring("on_error runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } @@ -220,9 +246,9 @@ class OnGetEntityTestParser : public xmlpp::SaxParser { } protected: - _xmlEntity* on_get_entity(const Glib::ustring& name) override + _xmlEntity* on_get_entity(const xmlpp::ustring& name) override { - g_assert_cmpstr(name.c_str(), ==, "number"); + assert(name == xmlpp::ustring("number")); throw std::runtime_error("on_get_entity runtime exception"); } }; @@ -235,12 +261,16 @@ void test_on_get_entity() { parser.parse_memory("]>&number;"); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_get_entity runtime exception"); + assert(e.what() == xmlpp::ustring("on_get_entity runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } @@ -261,22 +291,26 @@ void test_on_start_document() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_start_document runtime exception"); + assert(e.what() == xmlpp::ustring("on_start_document runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } class OnStartElementTestParser : public xmlpp::SaxParser { protected: - void on_start_element(const Glib::ustring& name, const xmlpp::SaxParser::AttributeList& attributes) override + void on_start_element(const xmlpp::ustring& name, const xmlpp::SaxParser::AttributeList& attributes) override { - g_assert_cmpstr(name.c_str(), ==, "b:root"); - g_assert_cmpint(attributes.size(), ==, 2); + assert(name == xmlpp::ustring("b:root")); + assert(attributes.size() == 2); throw std::runtime_error("on_start_element runtime exception"); } }; @@ -289,19 +323,21 @@ void test_on_start_element() { parser.parse_memory(""); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "on_start_element runtime exception"); + assert(e.what() == xmlpp::ustring("on_start_element runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } int main() { - Glib::init(); - test_on_cdata_block(); test_on_characters(); test_on_comment(); diff --git a/tests/saxparser_parse_stream_inconsistent_state/main.cc b/tests/saxparser_parse_stream_inconsistent_state/main.cc index ea8cf443..8e319284 100644 --- a/tests/saxparser_parse_stream_inconsistent_state/main.cc +++ b/tests/saxparser_parse_stream_inconsistent_state/main.cc @@ -11,17 +11,16 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with this library; if not, see . */ +#include + +#include #include -#include #include #include -#include - class MySaxParser : public xmlpp::SaxParser { protected: @@ -33,8 +32,6 @@ class MySaxParser : public xmlpp::SaxParser int main() { - Glib::init(); - { MySaxParser parser; @@ -44,12 +41,16 @@ int main() std::stringstream ss(""); parser.parse_stream(ss); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "some custom runtime exception"); + assert(e.what() == xmlpp::ustring("some custom runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); // Try parsing a different stream. exceptionThrown = false; @@ -62,14 +63,18 @@ int main() { // An "Attempt to start a second parse while a parse is in progress." parse // error should not have been thrown. - g_assert_not_reached(); + assert(false); } +#ifdef LIBXMLXX_HAVE_EXCEPTION_PTR catch(const std::runtime_error& e) +#else + catch(const xmlpp::exception& e) +#endif { exceptionThrown = true; - g_assert_cmpstr(e.what(), ==, "some custom runtime exception"); + assert(e.what() == xmlpp::ustring("some custom runtime exception")); } - g_assert_true(exceptionThrown); + assert(exceptionThrown); } return EXIT_SUCCESS; diff --git a/tools/build_scripts/tutorial-custom-cmd.py b/tools/build_scripts/tutorial-custom-cmd.py new file mode 100755 index 00000000..e69e074f --- /dev/null +++ b/tools/build_scripts/tutorial-custom-cmd.py @@ -0,0 +1,227 @@ +#!/usr/bin/env python3 + +# External command, intended to be called with custom_target() in meson.build + +# argv[1] argv[2:] +# tutorial-custom-cmd.py ... + +import os +import sys +import subprocess +import shutil + +subcommand = sys.argv[1] + +def insert_ex_code(): + # argv[2] argv[3] argv[4] argv[5] + # + + # Search for insert_example_code.py first in . + sys.path.insert(0, sys.argv[2]) + from insert_example_code import insert_example_code + + return insert_example_code(sys.argv[3], sys.argv[4], sys.argv[5]) + +def html(): + # argv[2] argv[3] + # + + input_xml_file = sys.argv[2] + output_html_dir = sys.argv[3] + + # Set the use.id.as.filename param so that we don't use the chapter / section + # number as the filename, otherwise the url will change every time anything is + # re-ordered or inserted in the documentation. + # For a list of available parameters, see http://docbook.sourceforge.net/release/xsl/current/doc/html/ + xslt_params = [ + '--param', 'toc.section.depth', '1', + '--stringparam', 'chunker.output.indent', 'yes', + '--stringparam', 'chunker.output.encoding', 'UTF-8', + '--stringparam', 'toc.list.type', 'ul', + '--param', 'use.id.as.filename', '1', + ] + + xslt_stylesheet = 'http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl' + + # Remove old files and create the destination directory. + shutil.rmtree(output_html_dir, ignore_errors=True) + os.makedirs(output_html_dir, exist_ok=True) + + cmd = [ + 'xsltproc', + ] + xslt_params + [ + '-o', output_html_dir + '/', + '--xinclude', + xslt_stylesheet, + input_xml_file, + ] + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, + universal_newlines=True) + # xsltproc prints the names of all written files. Don't print those lines. + for line in result.stdout.splitlines(): + if not line.startswith('Writing '): + print(line) + + return result.returncode + +def xmllint(): + from pathlib import Path + + # argv[2] argv[3] argv[4] + # + + validate = sys.argv[2] + input_xml_file = sys.argv[3] + stamp_file_path = sys.argv[4] + + relax_ng_schema = 'http://docbook.org/xml/5.0/rng/docbook.rng' + # schematron_schema = 'http://docbook.org/xml/5.0/sch/docbook.sch' + + # Validation against the Schematron schema does not work on Ubuntu 21.04: + # file:///usr/share/xml/docbook/schema/schematron/5.0/docbook.sch:6: element rule: + # Schemas parser error : Failed to compile context expression db:firstterm[@linkend] + # ..... + # Schematron schema http://docbook.org/xml/5.0/sch/docbook.sch failed to compile + + cmd = [ + 'xmllint', + '--noout', + '--noent', + '--xinclude', + ] + if validate == 'true': + cmd += [ + '--relaxng', relax_ng_schema, + #'--schematron', schematron_schema, + ] + cmd += [input_xml_file] + result = subprocess.run(cmd) + if result.returncode: + return result.returncode + + Path(stamp_file_path).touch(exist_ok=True) + return 0 + +# dblatex and xsltproc+fop generate a PDF file. +# docbook2pdf can generate PDF files from DocBook4 files, but not from DocBook5 files. +# xsltproc+xmlroff (version 0.6.3) does not seem to work acceptably. +def dblatex(): + # argv[2] argv[3] + # + # Create a PDF file, using dblatex. + + input_xml_file = sys.argv[2] + output_pdf_file = sys.argv[3] + + # For a list of available parameters, see http://dblatex.sourceforge.net/doc/manual/ + dblatex_params = [ + '-P', 'toc.section.depth=1', + '-P', 'paper.type=a4paper', + '-P', 'doc.collab.show=1', + '-P', 'latex.output.revhistory=0', + ] + + cmd = [ + 'dblatex', + ] + dblatex_params + [ + '-o', output_pdf_file, + '--pdf', + input_xml_file, + ] + return subprocess.run(cmd).returncode + +def fop(): + # argv[2] argv[3] + # + # Create a PDF file, using fop. + + input_xml_file = sys.argv[2] + output_pdf_file = sys.argv[3] + + fo_file = os.path.splitext(output_pdf_file)[0] + '.fo' + + # For a list of available parameters, see http://docbook.sourceforge.net/release/xsl/current/doc/fo/ + # For a list of available paper types, see the description of the page.width.portrait parameter. + xslt_params = [ + '--param', 'toc.section.depth', '1', + '--stringparam', 'fop1.extensions', '1', + '--stringparam', 'page.orientation', 'portrait', + '--stringparam', 'paper.type', 'A4', + ] + + xslt_stylesheet = 'http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl' + + # Generate a .fo (formatting object) file. + # fop can take an xslt stylesheet parameter, but it can only read local files. + # xsltproc is necessary if you want to read the stylesheet from the internet. + cmd = [ + 'xsltproc', + ] + xslt_params + [ + '-o', fo_file, + '--xinclude', + xslt_stylesheet, + input_xml_file, + ] + result = subprocess.run(cmd) + if result.returncode: + return result.returncode + + cmd = [ + 'fop', + '-fo', fo_file, + '-pdf', output_pdf_file, + ] + return subprocess.run(cmd).returncode + +# Invoked from meson.add_dist_script(). +def dist_doc(): + # argv[2] argv[3] argv[4] argv[5] + # + + # is a distribution directory, relative to MESON_PROJECT_DIST_ROOT. + # is a relative or absolute path in the build directory. + # is a relative or absolute path in the build directory. + # is a relative or absolute path in the build directory. + + # MESON_PROJECT_DIST_ROOT is set only if meson.version() >= 0.58.0. + project_dist_root = os.getenv('MESON_PROJECT_DIST_ROOT', os.getenv('MESON_DIST_ROOT')) + doc_dist_dir = os.path.join(project_dist_root, sys.argv[2]) + doc_build_dir = sys.argv[3] + xml_file = sys.argv[4] + pdf_file = sys.argv[5] + + # Create the distribution directory, if it does not exist. + os.makedirs(doc_dist_dir, exist_ok=True) + + # Distribute built XML file with example code inserted. + shutil.copy(xml_file, doc_dist_dir) + + # Distribute built html files. + shutil.copytree(os.path.join(doc_build_dir, 'html'), + os.path.join(doc_dist_dir, 'html'), + copy_function=shutil.copy) + + # If there is an updated PDF file, distribute it. + if os.path.isfile(pdf_file) and \ + os.stat(pdf_file).st_mtime > os.stat(xml_file).st_mtime: + shutil.copy(pdf_file, doc_dist_dir) + else: + print('--- Info: No updated PDF file found.') + + return 0 + +# ----- Main ----- +if subcommand == 'insert_example_code': + sys.exit(insert_ex_code()) +if subcommand == 'html': + sys.exit(html()) +if subcommand == 'xmllint': + sys.exit(xmllint()) +if subcommand == 'dblatex': + sys.exit(dblatex()) +if subcommand == 'fop': + sys.exit(fop()) +if subcommand == 'dist_doc': + sys.exit(dist_doc()) +print(sys.argv[0], ': illegal subcommand,', subcommand) +sys.exit(1) diff --git a/tools/conf_tests/have_exception_ptr.cc b/tools/conf_tests/have_exception_ptr.cc new file mode 100644 index 00000000..25bed7a4 --- /dev/null +++ b/tools/conf_tests/have_exception_ptr.cc @@ -0,0 +1,20 @@ +// Configuration-time test program, used in Meson build. +// Test whether std::exception_ptr, std::current_exception() and +// std::rethrow_exception() are defined. +// Corresponds to the M4 macro LIBXMLXX_CXX_HAS_EXCEPTION_PTR. + +#include + +int main() +{ + try + { + throw "custom error"; + } + catch (...) + { + std::exception_ptr ep = std::current_exception(); + std::rethrow_exception(ep); + } + return 0; +} diff --git a/untracked/README b/untracked/README new file mode 100644 index 00000000..a36b08f0 --- /dev/null +++ b/untracked/README @@ -0,0 +1,35 @@ +untracked/README + +This directory contains files not tracked by a source code control program, +such as git. (This README file is the exception.) + +The files can have one of two origins. + +1. Copied by the mm-common-get command. +2. Generated when libxml++ is built. + +Files of type 2 exist here only if libxml++ is built with maintainer-mode=false, +or the directory comes from a tarball. +Files of both types exist here only if libxml++ is built with Meson, +or the tarball is created with Meson. + +1. Files copied by mm-common-get +-------------------------------- +untracked/docs/doc_install.py or doc-install.pl + doc_postprocess.py or doc-postprocess.pl + doxygen-extra.css + tagfile-to-devhelp2.xsl +untracked/build_scripts/dist-build-scripts.py + dist-changelog.py + doc-reference.py + +mm-common-get may copy more files, but they are not used by libxml++. + +2. Generated files +------------------ +untracked/docs/reference/libxml++-5.0.devhelp2 + libxml++-5.0.tag + html/* +untracked/docs/manual/libxml++.pdf (only if build-pdf=true) + libxml++.xml + html/*